From 2dc9bdff775585ffe99c0b09867bcd1b5b5af5cb Mon Sep 17 00:00:00 2001 From: Kris O'Shea Date: Mon, 3 Jun 2024 23:39:05 +0100 Subject: [PATCH] add avs template --- .../.github/workflows/build-and-publish.yaml | 29 + .../.github/workflows/contracts-tests.yml | 27 + .../workflows/docker-compose-up-test.yaml | 36 + .../.github/workflows/docker-publish.yaml | 52 + .../.github/workflows/integration-tests.yml | 29 + .../.github/workflows/unit-tests.yml | 19 + temp-incredible-squaring-avs/.gitignore | 28 + temp-incredible-squaring-avs/.gitmodules | 6 + .../.vscode/settings.json | 3 + temp-incredible-squaring-avs/LICENSE | 98 + temp-incredible-squaring-avs/Makefile | 103 + temp-incredible-squaring-avs/README.md | 117 + .../aggregator/aggregator.go | 224 ++ .../aggregator/aggregator_test.go | 103 + .../aggregator/cmd/main.go | 64 + .../aggregator/mocks/chain.go | 74 + .../aggregator/rpc_server.go | 72 + .../aggregator/rpc_server_test.go | 81 + .../aggregator/types/types.go | 25 + .../challenger/challenger.go | 242 ++ .../challenger/challenger_test.go | 191 + .../challenger/cmd/main.go | 64 + .../challenger/mocks/chain.go | 81 + .../challenger/types/types.go | 17 + .../cli/actions/deposit_into_strategy.go | 54 + .../cli/actions/print_operator_status.go | 42 + .../cli/actions/register_operator_with_avs.go | 56 + .../register_operator_with_eigenlayer.go | 42 + temp-incredible-squaring-avs/cli/main.go | 67 + temp-incredible-squaring-avs/common/abi.go | 8 + .../abis/IncredibleSquaringTaskManager.json | 1198 ++++++ .../aggregator-docker-compose.yaml | 6 + .../config-files/aggregator.yaml | 6 + .../config-files/challenger.yaml | 4 + .../operator-docker-compose.anvil.yaml | 49 + .../config-files/operator.anvil.yaml | 44 + .../contracts/.github/workflows/test.yml | 34 + .../contracts/.gitignore | 15 + .../contracts/README.md | 66 + .../contracts/bindings/ERC20Mock/binding.go | 688 ++++ .../binding.go | 814 ++++ .../IncredibleSquaringTaskManager/binding.go | 2866 ++++++++++++++ .../contracts/foundry.toml | 30 + .../contracts/generate-go-bindings.sh | 31 + .../script/IncredibleSquaringDeployer.s.sol | 454 +++ ...edible_squaring_avs_deployment_output.json | 13 + .../31337/eigenlayer_deployment_output.json | 31 + .../contracts/script/utils/Utils.sol | 99 + .../contracts/src/ERC20Mock.sol | 308 ++ .../src/IIncredibleSquaringTaskManager.sol | 79 + .../src/IncredibleSquaringServiceManager.sol | 51 + .../src/IncredibleSquaringTaskManager.sol | 320 ++ .../test/CredibleSquaringTaskManager.t.sol | 53 + .../core/chainio/avs_reader.go | 76 + .../core/chainio/avs_subscriber.go | 80 + .../core/chainio/avs_writer.go | 149 + .../core/chainio/bindings.go | 65 + .../core/chainio/gen.go | 5 + .../core/chainio/mocks/avs_reader.go | 274 ++ .../core/chainio/mocks/avs_subscriber.go | 84 + .../core/chainio/mocks/avs_writer.go | 153 + .../core/chainio/mocks/tmp.go | 4 + .../core/config/config.go | 194 + temp-incredible-squaring-avs/core/utils.go | 79 + .../diagrams/architecture.png | Bin 0 -> 59577 bytes temp-incredible-squaring-avs/diagrams/uml.png | Bin 0 -> 130799 bytes .../docker-compose-build.yaml | 12 + .../docker-compose.yml | 131 + temp-incredible-squaring-avs/go.mod | 140 + temp-incredible-squaring-avs/go.sum | 657 ++++ .../dashboards/AVSs/incredible_squaring.json | 326 ++ .../dashboards/dashboard_provider.yml | 17 + .../dashboards/system/monitor_prometheus.json | 3412 +++++++++++++++++ .../provisioning/datasources/datasource.yml | 12 + .../metrics/metrics.go | 52 + .../metrics/noopmetrics.go | 19 + .../operator.Dockerfile | 17 + .../operator/cmd/main.go | 63 + temp-incredible-squaring-avs/operator/gen.go | 3 + .../operator/mocks/rpc_client.go | 51 + .../operator/operator.go | 342 ++ .../operator/operator_test.go | 110 + .../operator/registration.go | 183 + .../operator/registration_test.go | 54 + .../operator/rpc_client.go | 77 + .../plugin.Dockerfile | 15 + .../plugin/cmd/main.go | 247 ++ .../prometheus/prometheus.yml | 27 + .../deposit-into-mocktoken-strategy.sh | 17 + .../tests/anvil/README.md | 21 + ...s-and-eigenlayer-deployed-anvil-state.json | 1 + .../anvil/deploy-avs-save-anvil-state.sh | 44 + .../deploy-eigenlayer-save-anvil-state.sh | 35 + .../eigenlayer-deployed-anvil-state.json | 1 + .../tests/anvil/genesis.json | 49 + .../tests/anvil/operator-registration.sh | 3 + ...rt-anvil-chain-with-el-and-avs-deployed.sh | 42 + .../tests/anvil/utils.sh | 40 + .../tests/integration/integration_test.go | 242 ++ .../tests/keys/test.bls.key.json | 1 + .../tests/keys/test.ecdsa.key.json | 1 + temp-incredible-squaring-avs/tests/utils.go | 42 + .../types/avs_config.go | 20 + 103 files changed, 17002 insertions(+) create mode 100644 temp-incredible-squaring-avs/.github/workflows/build-and-publish.yaml create mode 100644 temp-incredible-squaring-avs/.github/workflows/contracts-tests.yml create mode 100644 temp-incredible-squaring-avs/.github/workflows/docker-compose-up-test.yaml create mode 100644 temp-incredible-squaring-avs/.github/workflows/docker-publish.yaml create mode 100644 temp-incredible-squaring-avs/.github/workflows/integration-tests.yml create mode 100644 temp-incredible-squaring-avs/.github/workflows/unit-tests.yml create mode 100644 temp-incredible-squaring-avs/.gitignore create mode 100644 temp-incredible-squaring-avs/.gitmodules create mode 100644 temp-incredible-squaring-avs/.vscode/settings.json create mode 100644 temp-incredible-squaring-avs/LICENSE create mode 100644 temp-incredible-squaring-avs/Makefile create mode 100644 temp-incredible-squaring-avs/README.md create mode 100644 temp-incredible-squaring-avs/aggregator/aggregator.go create mode 100644 temp-incredible-squaring-avs/aggregator/aggregator_test.go create mode 100644 temp-incredible-squaring-avs/aggregator/cmd/main.go create mode 100644 temp-incredible-squaring-avs/aggregator/mocks/chain.go create mode 100644 temp-incredible-squaring-avs/aggregator/rpc_server.go create mode 100644 temp-incredible-squaring-avs/aggregator/rpc_server_test.go create mode 100644 temp-incredible-squaring-avs/aggregator/types/types.go create mode 100644 temp-incredible-squaring-avs/challenger/challenger.go create mode 100644 temp-incredible-squaring-avs/challenger/challenger_test.go create mode 100644 temp-incredible-squaring-avs/challenger/cmd/main.go create mode 100644 temp-incredible-squaring-avs/challenger/mocks/chain.go create mode 100644 temp-incredible-squaring-avs/challenger/types/types.go create mode 100644 temp-incredible-squaring-avs/cli/actions/deposit_into_strategy.go create mode 100644 temp-incredible-squaring-avs/cli/actions/print_operator_status.go create mode 100644 temp-incredible-squaring-avs/cli/actions/register_operator_with_avs.go create mode 100644 temp-incredible-squaring-avs/cli/actions/register_operator_with_eigenlayer.go create mode 100644 temp-incredible-squaring-avs/cli/main.go create mode 100644 temp-incredible-squaring-avs/common/abi.go create mode 100644 temp-incredible-squaring-avs/common/abis/IncredibleSquaringTaskManager.json create mode 100644 temp-incredible-squaring-avs/config-files/aggregator-docker-compose.yaml create mode 100644 temp-incredible-squaring-avs/config-files/aggregator.yaml create mode 100644 temp-incredible-squaring-avs/config-files/challenger.yaml create mode 100644 temp-incredible-squaring-avs/config-files/operator-docker-compose.anvil.yaml create mode 100644 temp-incredible-squaring-avs/config-files/operator.anvil.yaml create mode 100644 temp-incredible-squaring-avs/contracts/.github/workflows/test.yml create mode 100644 temp-incredible-squaring-avs/contracts/.gitignore create mode 100644 temp-incredible-squaring-avs/contracts/README.md create mode 100644 temp-incredible-squaring-avs/contracts/bindings/ERC20Mock/binding.go create mode 100644 temp-incredible-squaring-avs/contracts/bindings/IncredibleSquaringServiceManager/binding.go create mode 100644 temp-incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager/binding.go create mode 100644 temp-incredible-squaring-avs/contracts/foundry.toml create mode 100755 temp-incredible-squaring-avs/contracts/generate-go-bindings.sh create mode 100644 temp-incredible-squaring-avs/contracts/script/IncredibleSquaringDeployer.s.sol create mode 100644 temp-incredible-squaring-avs/contracts/script/output/31337/credible_squaring_avs_deployment_output.json create mode 100644 temp-incredible-squaring-avs/contracts/script/output/31337/eigenlayer_deployment_output.json create mode 100644 temp-incredible-squaring-avs/contracts/script/utils/Utils.sol create mode 100644 temp-incredible-squaring-avs/contracts/src/ERC20Mock.sol create mode 100644 temp-incredible-squaring-avs/contracts/src/IIncredibleSquaringTaskManager.sol create mode 100644 temp-incredible-squaring-avs/contracts/src/IncredibleSquaringServiceManager.sol create mode 100644 temp-incredible-squaring-avs/contracts/src/IncredibleSquaringTaskManager.sol create mode 100644 temp-incredible-squaring-avs/contracts/test/CredibleSquaringTaskManager.t.sol create mode 100644 temp-incredible-squaring-avs/core/chainio/avs_reader.go create mode 100644 temp-incredible-squaring-avs/core/chainio/avs_subscriber.go create mode 100644 temp-incredible-squaring-avs/core/chainio/avs_writer.go create mode 100644 temp-incredible-squaring-avs/core/chainio/bindings.go create mode 100644 temp-incredible-squaring-avs/core/chainio/gen.go create mode 100644 temp-incredible-squaring-avs/core/chainio/mocks/avs_reader.go create mode 100644 temp-incredible-squaring-avs/core/chainio/mocks/avs_subscriber.go create mode 100644 temp-incredible-squaring-avs/core/chainio/mocks/avs_writer.go create mode 100644 temp-incredible-squaring-avs/core/chainio/mocks/tmp.go create mode 100644 temp-incredible-squaring-avs/core/config/config.go create mode 100644 temp-incredible-squaring-avs/core/utils.go create mode 100644 temp-incredible-squaring-avs/diagrams/architecture.png create mode 100644 temp-incredible-squaring-avs/diagrams/uml.png create mode 100644 temp-incredible-squaring-avs/docker-compose-build.yaml create mode 100644 temp-incredible-squaring-avs/docker-compose.yml create mode 100644 temp-incredible-squaring-avs/go.mod create mode 100644 temp-incredible-squaring-avs/go.sum create mode 100644 temp-incredible-squaring-avs/grafana/provisioning/dashboards/AVSs/incredible_squaring.json create mode 100644 temp-incredible-squaring-avs/grafana/provisioning/dashboards/dashboard_provider.yml create mode 100644 temp-incredible-squaring-avs/grafana/provisioning/dashboards/system/monitor_prometheus.json create mode 100644 temp-incredible-squaring-avs/grafana/provisioning/datasources/datasource.yml create mode 100644 temp-incredible-squaring-avs/metrics/metrics.go create mode 100644 temp-incredible-squaring-avs/metrics/noopmetrics.go create mode 100644 temp-incredible-squaring-avs/operator.Dockerfile create mode 100644 temp-incredible-squaring-avs/operator/cmd/main.go create mode 100644 temp-incredible-squaring-avs/operator/gen.go create mode 100644 temp-incredible-squaring-avs/operator/mocks/rpc_client.go create mode 100644 temp-incredible-squaring-avs/operator/operator.go create mode 100644 temp-incredible-squaring-avs/operator/operator_test.go create mode 100644 temp-incredible-squaring-avs/operator/registration.go create mode 100644 temp-incredible-squaring-avs/operator/registration_test.go create mode 100644 temp-incredible-squaring-avs/operator/rpc_client.go create mode 100644 temp-incredible-squaring-avs/plugin.Dockerfile create mode 100644 temp-incredible-squaring-avs/plugin/cmd/main.go create mode 100644 temp-incredible-squaring-avs/prometheus/prometheus.yml create mode 100755 temp-incredible-squaring-avs/scripts/deposit-into-mocktoken-strategy.sh create mode 100644 temp-incredible-squaring-avs/tests/anvil/README.md create mode 100644 temp-incredible-squaring-avs/tests/anvil/avs-and-eigenlayer-deployed-anvil-state.json create mode 100755 temp-incredible-squaring-avs/tests/anvil/deploy-avs-save-anvil-state.sh create mode 100755 temp-incredible-squaring-avs/tests/anvil/deploy-eigenlayer-save-anvil-state.sh create mode 100644 temp-incredible-squaring-avs/tests/anvil/eigenlayer-deployed-anvil-state.json create mode 100644 temp-incredible-squaring-avs/tests/anvil/genesis.json create mode 100755 temp-incredible-squaring-avs/tests/anvil/operator-registration.sh create mode 100755 temp-incredible-squaring-avs/tests/anvil/start-anvil-chain-with-el-and-avs-deployed.sh create mode 100644 temp-incredible-squaring-avs/tests/anvil/utils.sh create mode 100644 temp-incredible-squaring-avs/tests/integration/integration_test.go create mode 100644 temp-incredible-squaring-avs/tests/keys/test.bls.key.json create mode 100644 temp-incredible-squaring-avs/tests/keys/test.ecdsa.key.json create mode 100644 temp-incredible-squaring-avs/tests/utils.go create mode 100644 temp-incredible-squaring-avs/types/avs_config.go diff --git a/temp-incredible-squaring-avs/.github/workflows/build-and-publish.yaml b/temp-incredible-squaring-avs/.github/workflows/build-and-publish.yaml new file mode 100644 index 0000000..0bad324 --- /dev/null +++ b/temp-incredible-squaring-avs/.github/workflows/build-and-publish.yaml @@ -0,0 +1,29 @@ +name: ko-publish-aggregator-and-operator + +on: + push: + branches: ['master'] + # we can also trigger manually in case needed + workflow_dispatch: + +jobs: + publish: + name: Publish + runs-on: ubuntu-latest + permissions: + # Need this to be allowed to publish image to registry + # see https://docs.github.com/en/actions/publishing-packages/publishing-docker-images + packages: write + contents: read + steps: + - uses: actions/setup-go@v2 + with: + go-version: '1.21.x' + - uses: actions/checkout@v2 + + - uses: ko-build/setup-ko@v0.6 + # We build both the aggregator and the operator in the same job + # we could separate them, but anyways they share core/ so it would get messy + # See https://ko.build/configuration/#naming-images to understand --preserve-import-paths + - run: KO_DOCKER_REPO=ghcr.io/layr-labs/incredible-squaring ko build aggregator/cmd/main.go --preserve-import-paths + - run: KO_DOCKER_REPO=ghcr.io/layr-labs/incredible-squaring ko build operator/cmd/main.go --preserve-import-paths \ No newline at end of file diff --git a/temp-incredible-squaring-avs/.github/workflows/contracts-tests.yml b/temp-incredible-squaring-avs/.github/workflows/contracts-tests.yml new file mode 100644 index 0000000..1bbf76d --- /dev/null +++ b/temp-incredible-squaring-avs/.github/workflows/contracts-tests.yml @@ -0,0 +1,27 @@ +name: contracts-forge-tests + +on: + push: + branches: + - master + pull_request: + +jobs: + Test: + name: Contracts Forge Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Install forge dependencies + run: forge install + working-directory: ./contracts + + - name: Run tests + run: forge test -vvv + working-directory: ./contracts diff --git a/temp-incredible-squaring-avs/.github/workflows/docker-compose-up-test.yaml b/temp-incredible-squaring-avs/.github/workflows/docker-compose-up-test.yaml new file mode 100644 index 0000000..3c7b3ee --- /dev/null +++ b/temp-incredible-squaring-avs/.github/workflows/docker-compose-up-test.yaml @@ -0,0 +1,36 @@ +name: Docker Compose Up Test + +on: + push: + branches: + - master + pull_request: + +jobs: + docker-compose-test: + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v2 + + - name: Run Docker Compose + run: docker compose up -d + + - name: Sleep + run: sleep 60 + + - name: Check services running + run: | + if docker compose ps -a --filter="status=exited" --services | grep -v anvil-advance-chain-script | xargs grep -q; then + echo "Some services are not running" + exit 1 + fi + + # TODO: we should also add https://docs.docker.com/reference/dockerfile/#healthcheck to the aggregator and operator docker images + # then we could check on their health status (maybe the processes are still running, but they are logging a lot of errors and we want to catch that) + # - name: Check services health + # run: | + # if docker-compose -f docker-compose.yml ps -q | xargs docker inspect -f '{{ .State.Health.Status }}' | grep -v healthy; then + # echo "Some services are not healthy" + # exit 1 + # fi diff --git a/temp-incredible-squaring-avs/.github/workflows/docker-publish.yaml b/temp-incredible-squaring-avs/.github/workflows/docker-publish.yaml new file mode 100644 index 0000000..0fb04ad --- /dev/null +++ b/temp-incredible-squaring-avs/.github/workflows/docker-publish.yaml @@ -0,0 +1,52 @@ +name: docker-publish +on: + push: + branches: + - master + workflow_dispatch: + +env: + REGISTRY: ghcr.io + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + # Run this job only on push to master branch + if: github.event_name != 'pull_request' + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Setup Buildx + uses: docker/setup-buildx-action@v1 + with: + install: true + driver-opts: >- + image=moby/buildkit:master + + - name: Cache main image layers + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Build And Push Image + - name: Build Docker image + run: docker compose -f docker-compose-build.yaml build + - name: Push Docker image + run: docker compose -f docker-compose-build.yaml push \ No newline at end of file diff --git a/temp-incredible-squaring-avs/.github/workflows/integration-tests.yml b/temp-incredible-squaring-avs/.github/workflows/integration-tests.yml new file mode 100644 index 0000000..970dd7c --- /dev/null +++ b/temp-incredible-squaring-avs/.github/workflows/integration-tests.yml @@ -0,0 +1,29 @@ +name: integration-tests + +on: + push: + branches: + - master + pull_request: + +jobs: + Test: + name: Integration Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v4 + with: + go-version: '1.21' + + # we use forge right now as part of integration test, so need to install it first + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + - name: Install forge dependencies + run: forge install + working-directory: ./contracts + + - name: Test + run: make tests-integration \ No newline at end of file diff --git a/temp-incredible-squaring-avs/.github/workflows/unit-tests.yml b/temp-incredible-squaring-avs/.github/workflows/unit-tests.yml new file mode 100644 index 0000000..28ff49a --- /dev/null +++ b/temp-incredible-squaring-avs/.github/workflows/unit-tests.yml @@ -0,0 +1,19 @@ +name: unit-tests + +on: + push: + branches: + - master + pull_request: + +jobs: + Test: + name: Unit Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v4 + with: + go-version: '1.21' + - name: Test + run: make tests-unit \ No newline at end of file diff --git a/temp-incredible-squaring-avs/.gitignore b/temp-incredible-squaring-avs/.gitignore new file mode 100644 index 0000000..75f9597 --- /dev/null +++ b/temp-incredible-squaring-avs/.gitignore @@ -0,0 +1,28 @@ +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work +coverage.html + +# log files +logs.txt + +# just for example +id_rsa \ No newline at end of file diff --git a/temp-incredible-squaring-avs/.gitmodules b/temp-incredible-squaring-avs/.gitmodules new file mode 100644 index 0000000..140c014 --- /dev/null +++ b/temp-incredible-squaring-avs/.gitmodules @@ -0,0 +1,6 @@ +[submodule "contracts/lib/forge-std"] + path = contracts/lib/forge-std + url = https://github.com/foundry-rs/forge-std +[submodule "contracts/lib/eigenlayer-middleware"] + path = contracts/lib/eigenlayer-middleware + url = https://github.com/Layr-Labs/eigenlayer-middleware diff --git a/temp-incredible-squaring-avs/.vscode/settings.json b/temp-incredible-squaring-avs/.vscode/settings.json new file mode 100644 index 0000000..0fc7db5 --- /dev/null +++ b/temp-incredible-squaring-avs/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "solidity.compileUsingRemoteVersion": "v0.8.12+commit.f00d7308" +} \ No newline at end of file diff --git a/temp-incredible-squaring-avs/LICENSE b/temp-incredible-squaring-avs/LICENSE new file mode 100644 index 0000000..e83c44a --- /dev/null +++ b/temp-incredible-squaring-avs/LICENSE @@ -0,0 +1,98 @@ +Business Source License 1.1 + +License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. +"Business Source License" is a trademark of MariaDB Corporation Ab. + +----------------------------------------------------------------------------- + +Parameters + +Licensor: Layr Labs, Inc. + +Licensed Work: Incredible Squaring Avs + The Licensed Work is (c) 2023 Layr Labs, Inc. + +Additional Use Grant: None. + +Change Date: 2025-10-25 (October 25th, 2025) + +Change License: MIT + +----------------------------------------------------------------------------- + +Terms + +The Licensor hereby grants you the right to copy, modify, create derivative +works, redistribute, and make non-production use of the Licensed Work. The +Licensor may make an Additional Use Grant, above, permitting limited +production use. + +Effective on the Change Date, or the fourth anniversary of the first publicly +available distribution of a specific version of the Licensed Work under this +License, whichever comes first, the Licensor hereby grants you rights under +the terms of the Change License, and the rights granted in the paragraph +above terminate. + +If your use of the Licensed Work does not comply with the requirements +currently in effect as described in this License, you must purchase a +commercial license from the Licensor, its affiliated entities, or authorized +resellers, or you must refrain from using the Licensed Work. + +All copies of the original and modified Licensed Work, and derivative works +of the Licensed Work, are subject to this License. This License applies +separately for each version of the Licensed Work and the Change Date may vary +for each version of the Licensed Work released by Licensor. + +You must conspicuously display this License on each original or modified copy +of the Licensed Work. If you receive the Licensed Work in original or +modified form from a third party, the terms and conditions set forth in this +License apply to your use of that work. + +Any use of the Licensed Work in violation of this License will automatically +terminate your rights under this License for the current and all other +versions of the Licensed Work. + +This License does not grant you any right in any trademark or logo of +Licensor or its affiliates (provided that you may use a trademark or logo of +Licensor as expressly required by this License). + +TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON +AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, +EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND +TITLE. + +MariaDB hereby grants you permission to use this License’s text to license +your works, and to refer to it using the trademark "Business Source License", +as long as you comply with the Covenants of Licensor below. + +----------------------------------------------------------------------------- + +Covenants of Licensor + +In consideration of the right to use this License’s text and the "Business +Source License" name and trademark, Licensor covenants to MariaDB, and to all +other recipients of the licensed work to be provided by Licensor: + +1. To specify as the Change License the GPL Version 2.0 or any later version, + or a license that is compatible with GPL Version 2.0 or a later version, + where "compatible" means that software provided under the Change License can + be included in a program with software provided under GPL Version 2.0 or a + later version. Licensor may specify additional Change Licenses without + limitation. + +2. To either: (a) specify an additional grant of rights to use that does not + impose any additional restriction on the right granted in this License, as + the Additional Use Grant; or (b) insert the text "None". + +3. To specify a Change Date. + +4. Not to modify this License in any other way. + +----------------------------------------------------------------------------- + +Notice + +The Business Source License (this document, or the "License") is not an Open +Source license. However, the Licensed Work will eventually be made available +under an Open Source License, as stated in this License. \ No newline at end of file diff --git a/temp-incredible-squaring-avs/Makefile b/temp-incredible-squaring-avs/Makefile new file mode 100644 index 0000000..6b7fba5 --- /dev/null +++ b/temp-incredible-squaring-avs/Makefile @@ -0,0 +1,103 @@ +############################# HELP MESSAGE ############################# +# Make sure the help command stays first, so that it's printed by default when `make` is called without arguments +.PHONY: help tests +help: + @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +AGGREGATOR_ECDSA_PRIV_KEY=0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6 +CHALLENGER_ECDSA_PRIV_KEY=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a + +CHAINID=31337 +# Make sure to update this if the strategy address changes +# check in contracts/script/output/${CHAINID}/credible_squaring_avs_deployment_output.json +STRATEGY_ADDRESS=0x7a2088a1bFc9d81c55368AE168C2C02570cB814F +DEPLOYMENT_FILES_DIR=contracts/script/output/${CHAINID} + +-----------------------------: ## + +___CONTRACTS___: ## + +build-contracts: ## builds all contracts + cd contracts && forge build + +deploy-eigenlayer-contracts-to-anvil-and-save-state: ## Deploy eigenlayer + ./tests/anvil/deploy-eigenlayer-save-anvil-state.sh + +deploy-incredible-squaring-contracts-to-anvil-and-save-state: ## Deploy avs + ./tests/anvil/deploy-avs-save-anvil-state.sh + +deploy-all-to-anvil-and-save-state: deploy-eigenlayer-contracts-to-anvil-and-save-state deploy-incredible-squaring-contracts-to-anvil-and-save-state ## deploy eigenlayer, shared avs contracts, and inc-sq contracts + +start-anvil-chain-with-el-and-avs-deployed: ## starts anvil from a saved state file (with el and avs contracts deployed) + ./tests/anvil/start-anvil-chain-with-el-and-avs-deployed.sh + +bindings: ## generates contract bindings + cd contracts && ./generate-go-bindings.sh + +___DOCKER___: ## +docker-build-and-publish-images: ## builds and publishes operator and aggregator docker images using Ko + KO_DOCKER_REPO=ghcr.io/layr-labs/incredible-squaring ko build aggregator/cmd/main.go --preserve-import-paths + KO_DOCKER_REPO=ghcr.io/layr-labs/incredible-squaring ko build operator/cmd/main.go --preserve-import-paths +docker-compose-up: ## runs docker compose pull first and then up + docker compose pull && docker compose up -d + +__CLI__: ## + +cli-setup-operator: send-fund cli-register-operator-with-eigenlayer cli-deposit-into-mocktoken-strategy cli-register-operator-with-avs ## registers operator with eigenlayer and avs + +cli-register-operator-with-eigenlayer: ## registers operator with delegationManager + go run cli/main.go --config config-files/operator.anvil.yaml register-operator-with-eigenlayer + +cli-deposit-into-mocktoken-strategy: ## + ./scripts/deposit-into-mocktoken-strategy.sh + +cli-register-operator-with-avs: ## + go run cli/main.go --config config-files/operator.anvil.yaml register-operator-with-avs + +cli-deregister-operator-with-avs: ## + go run cli/main.go --config config-files/operator.anvil.yaml deregister-operator-with-avs + +cli-print-operator-status: ## + go run cli/main.go --config config-files/operator.anvil.yaml print-operator-status + +send-fund: ## sends fund to the operator saved in tests/keys/test.ecdsa.key.json + cast send 0x860B6912C2d0337ef05bbC89b0C2CB6CbAEAB4A5 --value 10ether --private-key 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6 + +-----------------------------: ## +# We pipe all zapper logs through https://github.com/maoueh/zap-pretty so make sure to install it +# TODO: piping to zap-pretty only works when zapper environment is set to production, unsure why +____OFFCHAIN_SOFTWARE___: ## +start-aggregator: ## + go run aggregator/cmd/main.go --config config-files/aggregator.yaml \ + --credible-squaring-deployment ${DEPLOYMENT_FILES_DIR}/credible_squaring_avs_deployment_output.json \ + --ecdsa-private-key ${AGGREGATOR_ECDSA_PRIV_KEY} \ + 2>&1 | zap-pretty + +start-operator: ## + go run operator/cmd/main.go --config config-files/operator.anvil.yaml \ + 2>&1 | zap-pretty + +start-challenger: ## + go run challenger/cmd/main.go --config config-files/challenger.yaml \ + --credible-squaring-deployment ${DEPLOYMENT_FILES_DIR}/credible_squaring_avs_deployment_output.json \ + --ecdsa-private-key ${CHALLENGER_ECDSA_PRIV_KEY} \ + 2>&1 | zap-pretty + +run-plugin: ## + go run plugin/cmd/main.go --config config-files/operator.anvil.yaml +-----------------------------: ## +_____HELPER_____: ## +mocks: ## generates mocks for tests + go install go.uber.org/mock/mockgen@v0.3.0 + go generate ./... + +tests-unit: ## runs all unit tests + go test $$(go list ./... | grep -v /integration) -coverprofile=coverage.out -covermode=atomic --timeout 15s + go tool cover -html=coverage.out -o coverage.html + +tests-contract: ## runs all forge tests + cd contracts && forge test + +tests-integration: ## runs all integration tests + go test ./tests/integration/... -v -count=1 + diff --git a/temp-incredible-squaring-avs/README.md b/temp-incredible-squaring-avs/README.md new file mode 100644 index 0000000..6d9a80c --- /dev/null +++ b/temp-incredible-squaring-avs/README.md @@ -0,0 +1,117 @@ +# Incredible Squaring AVS + +[![Go Report Card](https://goreportcard.com/badge/github.com/Layr-Labs/incredible-squaring-avs)](https://goreportcard.com/report/github.com/Layr-Labs/incredible-squaring-avs) + + Do not use it in Production, testnet only. + +Basic repo demoing a simple AVS middleware with full eigenlayer integration. See this [video walkthrough](https://www.loom.com/share/50314b3ec0f34e2ba386d45724602d76?sid=9d68d8cb-d2d5-4123-bd06-776de2076de0). + +## Dependencies + +You will need [foundry](https://book.getfoundry.sh/getting-started/installation) and [zap-pretty](https://github.com/maoueh/zap-pretty) and docker to run the examples below. +``` +curl -L https://foundry.paradigm.xyz | bash +foundryup +go install github.com/maoueh/zap-pretty@latest +``` +You will also need to [install docker](https://docs.docker.com/get-docker/), and build the contracts: +``` +make build-contracts +``` + +## Running via make + +This simple session illustrates the basic flow of the AVS. The makefile commands are hardcoded for a single operator, but it's however easy to create new operator config files, and start more operators manually (see the actual commands that the makefile calls). + +Start anvil in a separate terminal: + +```bash +make start-anvil-chain-with-el-and-avs-deployed +``` + +The above command starts a local anvil chain from a [saved state](./tests/anvil/avs-and-eigenlayer-deployed-anvil-state.json) with eigenlayer and incredible-squaring contracts already deployed (but no operator registered). + +Start the aggregator: + +```bash +make start-aggregator +``` + +Register the operator with eigenlayer and incredible-squaring, and then start the process: + +```bash +make start-operator +``` + +> By default, the `start-operator` command will also setup the operator (see `register_operator_on_startup` flag in `config-files/operator.anvil.yaml`). To disable this, set `register_operator_on_startup` to false, and run `make cli-setup-operator` before running `start-operator`. + +## Running via docker compose + +We wrote a [docker-compose.yml](./docker-compose.yml) file to run and test everything on a single machine. It will start an anvil instance, loading a [state](./tests/anvil/avs-and-eigenlayer-deployed-anvil-state.json) where the eigenlayer and incredible-squaring contracts are deployed, start the aggregator, and finally one operator, along with prometheus and grafana servers. The grafana server will be available at http://localhost:3000, with user and password both set to `admin`. We have created a simple [grafana dashboard](./grafana/provisioning/dashboards/AVSs/incredible_squaring.json) which can be used as a starting example and expanded to include AVS specific metrics. The eigen metrics should not be added to this dashboard as they will be exposed on the main eigenlayer dashboard provided by the eigenlayer-cli. + +## Avs Task Description + +The architecture of the AVS contains: + +- [Eigenlayer core](https://github.com/Layr-Labs/eigenlayer-contracts/tree/master) contracts +- AVS contracts + - [ServiceManager](contracts/src/IncredibleSquaringServiceManager.sol) which will eventually contain slashing logic but for M2 is just a placeholder. + - [TaskManager](contracts/src/IncredibleSquaringTaskManager.sol) which contains [task creation](contracts/src/IncredibleSquaringTaskManager.sol#L83) and [task response](contracts/src/IncredibleSquaringTaskManager.sol#L102) logic. + - The [challenge](contracts/src/IncredibleSquaringTaskManager.sol#L176) logic could be separated into its own contract, but we have decided to include it in the TaskManager for this simple task. + - Set of [registry contracts](https://github.com/Layr-Labs/eigenlayer-middleware) to manage operators opted in to this avs +- Task Generator + - in a real world scenario, this could be a separate entity, but for this simple demo, the aggregator also acts as the task generator +- Aggregator + - aggregates BLS signatures from operators and posts the aggregated response to the task manager + - For this simple demo, the aggregator is not an operator, and thus does not need to register with eigenlayer or the AVS contract. It's IP address is simply hardcoded into the operators' config. +- Operators + - Square the number sent to the task manager by the task generator, sign it, and send it to the aggregator + +![](./diagrams/architecture.png) + +1. A task generator (in our case, same as the aggregator) publishes tasks once every regular interval (say 10 blocks, you are free to set your own interval) to the IncredibleSquaringTaskManager contract's [createNewTask](contracts/src/IncredibleSquaringTaskManager.sol#L83) function. Each task specifies an integer `numberToBeSquared` for which it wants the currently opted-in operators to determine its square `numberToBeSquared^2`. `createNewTask` also takes `quorumNumbers` and `quorumThresholdPercentage` which requests that each listed quorum (we only use quorumNumber 0 in incredible-squaring) needs to reach at least thresholdPercentage of operator signatures. + +2. A [registry](https://github.com/Layr-Labs/eigenlayer-middleware/blob/master/src/BLSRegistryCoordinatorWithIndices.sol) contract is deployed that allows any eigenlayer operator with at least 1 delegated [mockerc20](contracts/src/ERC20Mock.sol) token to opt-in to this AVS and also de-register from this AVS. + +3. [Operator] The operators who are currently opted-in with the AVS need to read the task number from the Task contract, compute its square, sign on that computed result (over the BN254 curve) and send their taskResponse and signature to the aggregator. + +4. [Aggregator] The aggregator collects the signatures from the operators and aggregates them using BLS aggregation. If any response passes the [quorumThresholdPercentage](contracts/src/IIncredibleSquaringTaskManager.sol#L36) set by the task generator when posting the task, the aggregator posts the aggregated response to the Task contract. + +5. If a response was sent within the [response window](contracts/src/IncredibleSquaringTaskManager.sol#L119), we enter the [Dispute resolution] period. + - [Off-chain] A challenge window is launched during which anyone can [raise a dispute](contracts/src/IncredibleSquaringTaskManager.sol#L171) in a DisputeResolution contract (in our case, this is the same as the TaskManager contract) + - [On-chain] The DisputeResolution contract resolves that a particular operator’s response is not the correct response (that is, not the square of the integer specified in the task) or the opted-in operator didn’t respond during the response window. If the dispute is resolved, the operator will be frozen in the Registration contract and the veto committee will decide whether to veto the freezing request or not. + +Below is a more detailed uml diagram of the aggregator and operator processes: + +![](./diagrams/uml.png) + +## Avs node spec compliance + +Every AVS node implementation is required to abide by the [Eigenlayer AVS Node Specification](https://docs.eigenlayer.xyz/category/node-specification). We suggest reading through the whole spec, including the keys management section, but the hard requirements are currently only to: +- implement the [AVS Node API](https://docs.eigenlayer.xyz/category/avs-node-api) +- implement the [eigen prometheus metrics](https://docs.eigenlayer.xyz/category/metrics) + +If you are using golang, you can use our [metrics](https://github.com/Layr-Labs/eigensdk-go/tree/master/metrics) and [nodeapi](https://github.com/Layr-Labs/eigensdk-go/tree/master/nodeapi) implementation in the [eigensdk](https://github.com/Layr-Labs/eigensdk-go), just like this repo does. Otherwise, you will have to implement it on your own. + +## StakeUpdates Cronjob + +AVS Registry contracts have a stale view of operator shares in the delegation manager contract. In order to update their stake table, they need to periodically call the [StakeRegistry.updateStakes()](https://github.com/Layr-Labs/eigenlayer-middleware/blob/f171a0812126bbb0bb6d44f53c622591a643e987/src/StakeRegistry.sol#L76) function. We are currently writing a cronjob binary to do this for you, will be open sourced soon! + +## Integration Tests + +See the integration tests [README](tests/anvil/README.md) for more details. + +## Troubleshooting + +### Received error from aggregator + +When running on anvil, a typical log for the operator is +``` +[2024-04-09 18:25:08.647 PDT] INFO (logging/zap_logger.go:49) rpc client is nil. Dialing aggregator rpc client +[2024-04-09 18:25:08.650 PDT] INFO (logging/zap_logger.go:49) Sending signed task response header to aggregator {"signedTaskResponse":"\u0026aggregator.SignedTaskResponse{TaskResponse:contractIncredibleSquaringTaskManager.IIncredibleSquaringTaskManagerTaskResponse{ReferenceTaskIndex:0x2, NumberSquared:4}, BlsSignature:bls.Signature{G1Point:(*bls.G1Point)(0x14000282068)}, OperatorId:[32]uint8{0xc4, 0xc2, 0x10, 0x30, 0xe, 0x28, 0xab, 0x4b, 0xa7, 0xb, 0x7f, 0xbb, 0xe, 0xfa, 0x55, 0x7d, 0x2a, 0x2a, 0x5f, 0x1f, 0xbf, 0xa6, 0xf8, 0x56, 0xe4, 0xcf, 0x3e, 0x9d, 0x76, 0x6a, 0x21, 0xdc}}"} +[2024-04-09 18:25:08.651 PDT] INFO (logging/zap_logger.go:49) Received error from aggregator {"err":"task 2 not initialized or already completed"} +[2024-04-09 18:25:08.651 PDT] INFO (logging/zap_logger.go:69) Retrying in 2 seconds +[2024-04-09 18:25:10.679 PDT] INFO (logging/zap_logger.go:49) Signed task response header accepted by aggregator. {"reply":false} +``` + +The error `task 2 not initialized or already completed` is expected behavior. This is because the aggregator needs to setup its data structures before it can accept responses. But on a local anvil setup, the operator had time to receive the websocket event for the new task, square the number, sign the response, and send it to the aggregator process before the aggregator has finalized its setup. Hence, the operator retries sending the response 2 seconds later and it is accepted. \ No newline at end of file diff --git a/temp-incredible-squaring-avs/aggregator/aggregator.go b/temp-incredible-squaring-avs/aggregator/aggregator.go new file mode 100644 index 0000000..0b5d260 --- /dev/null +++ b/temp-incredible-squaring-avs/aggregator/aggregator.go @@ -0,0 +1,224 @@ +package aggregator + +import ( + "context" + "math/big" + "sync" + "time" + + "github.com/Layr-Labs/eigensdk-go/logging" + + "github.com/Layr-Labs/eigensdk-go/chainio/clients" + sdkclients "github.com/Layr-Labs/eigensdk-go/chainio/clients" + "github.com/Layr-Labs/eigensdk-go/services/avsregistry" + blsagg "github.com/Layr-Labs/eigensdk-go/services/bls_aggregation" + oprsinfoserv "github.com/Layr-Labs/eigensdk-go/services/operatorsinfo" + sdktypes "github.com/Layr-Labs/eigensdk-go/types" + "github.com/Layr-Labs/incredible-squaring-avs/aggregator/types" + "github.com/Layr-Labs/incredible-squaring-avs/core" + "github.com/Layr-Labs/incredible-squaring-avs/core/chainio" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" + + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" +) + +const ( + // number of blocks after which a task is considered expired + // this hardcoded here because it's also hardcoded in the contracts, but should + // ideally be fetched from the contracts + taskChallengeWindowBlock = 100 + blockTimeSeconds = 12 * time.Second + avsName = "incredible-squaring" +) + +// Aggregator sends tasks (numbers to square) onchain, then listens for operator signed TaskResponses. +// It aggregates responses signatures, and if any of the TaskResponses reaches the QuorumThresholdPercentage for each quorum +// (currently we only use a single quorum of the ERC20Mock token), it sends the aggregated TaskResponse and signature onchain. +// +// The signature is checked in the BLSSignatureChecker.sol contract, which expects a +// +// struct NonSignerStakesAndSignature { +// uint32[] nonSignerQuorumBitmapIndices; +// BN254.G1Point[] nonSignerPubkeys; +// BN254.G1Point[] quorumApks; +// BN254.G2Point apkG2; +// BN254.G1Point sigma; +// uint32[] quorumApkIndices; +// uint32[] totalStakeIndices; +// uint32[][] nonSignerStakeIndices; // nonSignerStakeIndices[quorumNumberIndex][nonSignerIndex] +// } +// +// A task can only be responded onchain by having enough operators sign on it such that their stake in each quorum reaches the QuorumThresholdPercentage. +// In order to verify this onchain, the Registry contracts store the history of stakes and aggregate pubkeys (apks) for each operators and each quorum. These are +// updated everytime an operator registers or deregisters with the BLSRegistryCoordinatorWithIndices.sol contract, or calls UpdateStakes() on the StakeRegistry.sol contract, +// after having received new delegated shares or having delegated shares removed by stakers queuing withdrawals. Each of these pushes to their respective datatype array a new entry. +// +// This is true for quorumBitmaps (represent the quorums each operator is opted into), quorumApks (apks per quorum), totalStakes (total stake per quorum), and nonSignerStakes (stake per quorum per operator). +// The 4 "indices" in NonSignerStakesAndSignature basically represent the index at which to fetch their respective data, given a blockNumber at which the task was created. +// Note that different data types might have different indices, since for eg QuorumBitmaps are updated for operators registering/deregistering, but not for UpdateStakes. +// Thankfully, we have deployed a helper contract BLSOperatorStateRetriever.sol whose function getCheckSignaturesIndices() can be used to fetch the indices given a block number. +// +// The 4 other fields nonSignerPubkeys, quorumApks, apkG2, and sigma, however, must be computed individually. +// apkG2 and sigma are just the aggregated signature and pubkeys of the operators who signed the task response (aggregated over all quorums, so individual signatures might be duplicated). +// quorumApks are the G1 aggregated pubkeys of the operators who signed the task response, but one per quorum, as opposed to apkG2 which is summed over all quorums. +// nonSignerPubkeys are the G1 pubkeys of the operators who did not sign the task response, but were opted into the quorum at the blocknumber at which the task was created. +// Upon sending a task onchain (or receiving a NewTaskCreated Event if the tasks were sent by an external task generator), the aggregator can get the list of all operators opted into each quorum at that +// block number by calling the getOperatorState() function of the BLSOperatorStateRetriever.sol contract. +type Aggregator struct { + logger logging.Logger + serverIpPortAddr string + avsWriter chainio.AvsWriterer + // aggregation related fields + blsAggregationService blsagg.BlsAggregationService + tasks map[types.TaskIndex]cstaskmanager.IIncredibleSquaringTaskManagerTask + tasksMu sync.RWMutex + taskResponses map[types.TaskIndex]map[sdktypes.TaskResponseDigest]cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse + taskResponsesMu sync.RWMutex +} + +// NewAggregator creates a new Aggregator with the provided config. +func NewAggregator(c *config.Config) (*Aggregator, error) { + + avsReader, err := chainio.BuildAvsReaderFromConfig(c) + if err != nil { + c.Logger.Error("Cannot create avsReader", "err", err) + return nil, err + } + + avsWriter, err := chainio.BuildAvsWriterFromConfig(c) + if err != nil { + c.Logger.Errorf("Cannot create avsWriter", "err", err) + return nil, err + } + + chainioConfig := sdkclients.BuildAllConfig{ + EthHttpUrl: c.EthHttpRpcUrl, + EthWsUrl: c.EthWsRpcUrl, + RegistryCoordinatorAddr: c.IncredibleSquaringRegistryCoordinatorAddr.String(), + OperatorStateRetrieverAddr: c.OperatorStateRetrieverAddr.String(), + AvsName: avsName, + PromMetricsIpPortAddress: ":9090", + } + clients, err := clients.BuildAll(chainioConfig, c.EcdsaPrivateKey, c.Logger) + if err != nil { + c.Logger.Errorf("Cannot create sdk clients", "err", err) + return nil, err + } + + operatorPubkeysService := oprsinfoserv.NewOperatorsInfoServiceInMemory(context.Background(), clients.AvsRegistryChainSubscriber, clients.AvsRegistryChainReader, c.Logger) + avsRegistryService := avsregistry.NewAvsRegistryServiceChainCaller(avsReader, operatorPubkeysService, c.Logger) + blsAggregationService := blsagg.NewBlsAggregatorService(avsRegistryService, c.Logger) + + return &Aggregator{ + logger: c.Logger, + serverIpPortAddr: c.AggregatorServerIpPortAddr, + avsWriter: avsWriter, + blsAggregationService: blsAggregationService, + tasks: make(map[types.TaskIndex]cstaskmanager.IIncredibleSquaringTaskManagerTask), + taskResponses: make(map[types.TaskIndex]map[sdktypes.TaskResponseDigest]cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse), + }, nil +} + +func (agg *Aggregator) Start(ctx context.Context) error { + agg.logger.Infof("Starting aggregator.") + agg.logger.Infof("Starting aggregator rpc server.") + go agg.startServer(ctx) + + // TODO(soubhik): refactor task generation/sending into a separate function that we can run as goroutine + ticker := time.NewTicker(10 * time.Second) + agg.logger.Infof("Aggregator set to send new task every 10 seconds...") + defer ticker.Stop() + taskNum := int64(0) + // ticker doesn't tick immediately, so we send the first task here + // see https://github.com/golang/go/issues/17601 + _ = agg.sendNewTask(big.NewInt(taskNum)) + taskNum++ + + for { + select { + case <-ctx.Done(): + return nil + case blsAggServiceResp := <-agg.blsAggregationService.GetResponseChannel(): + agg.logger.Info("Received response from blsAggregationService", "blsAggServiceResp", blsAggServiceResp) + agg.sendAggregatedResponseToContract(blsAggServiceResp) + case <-ticker.C: + err := agg.sendNewTask(big.NewInt(taskNum)) + taskNum++ + if err != nil { + // we log the errors inside sendNewTask() so here we just continue to the next task + continue + } + } + } +} + +func (agg *Aggregator) sendAggregatedResponseToContract(blsAggServiceResp blsagg.BlsAggregationServiceResponse) { + // TODO: check if blsAggServiceResp contains an err + if blsAggServiceResp.Err != nil { + agg.logger.Error("BlsAggregationServiceResponse contains an error", "err", blsAggServiceResp.Err) + // panicing to help with debugging (fail fast), but we shouldn't panic if we run this in production + panic(blsAggServiceResp.Err) + } + nonSignerPubkeys := []cstaskmanager.BN254G1Point{} + for _, nonSignerPubkey := range blsAggServiceResp.NonSignersPubkeysG1 { + nonSignerPubkeys = append(nonSignerPubkeys, core.ConvertToBN254G1Point(nonSignerPubkey)) + } + quorumApks := []cstaskmanager.BN254G1Point{} + for _, quorumApk := range blsAggServiceResp.QuorumApksG1 { + quorumApks = append(quorumApks, core.ConvertToBN254G1Point(quorumApk)) + } + nonSignerStakesAndSignature := cstaskmanager.IBLSSignatureCheckerNonSignerStakesAndSignature{ + NonSignerPubkeys: nonSignerPubkeys, + QuorumApks: quorumApks, + ApkG2: core.ConvertToBN254G2Point(blsAggServiceResp.SignersApkG2), + Sigma: core.ConvertToBN254G1Point(blsAggServiceResp.SignersAggSigG1.G1Point), + NonSignerQuorumBitmapIndices: blsAggServiceResp.NonSignerQuorumBitmapIndices, + QuorumApkIndices: blsAggServiceResp.QuorumApkIndices, + TotalStakeIndices: blsAggServiceResp.TotalStakeIndices, + NonSignerStakeIndices: blsAggServiceResp.NonSignerStakeIndices, + } + + agg.logger.Info("Threshold reached. Sending aggregated response onchain.", + "taskIndex", blsAggServiceResp.TaskIndex, + ) + agg.tasksMu.RLock() + task := agg.tasks[blsAggServiceResp.TaskIndex] + agg.tasksMu.RUnlock() + agg.taskResponsesMu.RLock() + taskResponse := agg.taskResponses[blsAggServiceResp.TaskIndex][blsAggServiceResp.TaskResponseDigest] + agg.taskResponsesMu.RUnlock() + _, err := agg.avsWriter.SendAggregatedResponse(context.Background(), task, taskResponse, nonSignerStakesAndSignature) + if err != nil { + agg.logger.Error("Aggregator failed to respond to task", "err", err) + } +} + +// sendNewTask sends a new task to the task manager contract, and updates the Task dict struct +// with the information of operators opted into quorum 0 at the block of task creation. +func (agg *Aggregator) sendNewTask(numToSquare *big.Int) error { + agg.logger.Info("Aggregator sending new task", "numberToSquare", numToSquare) + // Send number to square to the task manager contract + newTask, taskIndex, err := agg.avsWriter.SendNewTaskNumberToSquare(context.Background(), numToSquare, types.QUORUM_THRESHOLD_NUMERATOR, types.QUORUM_NUMBERS) + if err != nil { + agg.logger.Error("Aggregator failed to send number to square", "err", err) + return err + } + + agg.tasksMu.Lock() + agg.tasks[taskIndex] = newTask + agg.tasksMu.Unlock() + + quorumThresholdPercentages := make(sdktypes.QuorumThresholdPercentages, len(newTask.QuorumNumbers)) + for i := range newTask.QuorumNumbers { + quorumThresholdPercentages[i] = sdktypes.QuorumThresholdPercentage(newTask.QuorumThresholdPercentage) + } + // TODO(samlaf): we use seconds for now, but we should ideally pass a blocknumber to the blsAggregationService + // and it should monitor the chain and only expire the task aggregation once the chain has reached that block number. + taskTimeToExpiry := taskChallengeWindowBlock * blockTimeSeconds + var quorumNums sdktypes.QuorumNums + for _, quorumNum := range newTask.QuorumNumbers { + quorumNums = append(quorumNums, sdktypes.QuorumNum(quorumNum)) + } + agg.blsAggregationService.InitializeNewTask(taskIndex, newTask.TaskCreatedBlock, quorumNums, quorumThresholdPercentages, taskTimeToExpiry) + return nil +} diff --git a/temp-incredible-squaring-avs/aggregator/aggregator_test.go b/temp-incredible-squaring-avs/aggregator/aggregator_test.go new file mode 100644 index 0000000..8f5bae6 --- /dev/null +++ b/temp-incredible-squaring-avs/aggregator/aggregator_test.go @@ -0,0 +1,103 @@ +package aggregator + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + gethcore "github.com/ethereum/go-ethereum/core" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" + + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + sdklogging "github.com/Layr-Labs/eigensdk-go/logging" + blsaggservmock "github.com/Layr-Labs/eigensdk-go/services/mocks/blsagg" + sdktypes "github.com/Layr-Labs/eigensdk-go/types" + + "github.com/Layr-Labs/incredible-squaring-avs/aggregator/mocks" + "github.com/Layr-Labs/incredible-squaring-avs/aggregator/types" + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + chainiomocks "github.com/Layr-Labs/incredible-squaring-avs/core/chainio/mocks" +) + +var MOCK_OPERATOR_ID = [32]byte{207, 73, 226, 221, 104, 100, 123, 41, 192, 3, 9, 119, 90, 83, 233, 159, 231, 151, 245, 96, 150, 48, 144, 27, 102, 253, 39, 101, 1, 26, 135, 173} +var MOCK_OPERATOR_STAKE = big.NewInt(100) +var MOCK_OPERATOR_BLS_PRIVATE_KEY_STRING = "50" + +type MockTask struct { + TaskNum uint32 + BlockNumber uint32 + NumberToSquare uint32 +} + +func TestSendNewTask(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + MOCK_OPERATOR_BLS_PRIVATE_KEY, err := bls.NewPrivateKey(MOCK_OPERATOR_BLS_PRIVATE_KEY_STRING) + assert.Nil(t, err) + MOCK_OPERATOR_KEYPAIR := bls.NewKeyPair(MOCK_OPERATOR_BLS_PRIVATE_KEY) + MOCK_OPERATOR_G1PUBKEY := MOCK_OPERATOR_KEYPAIR.GetPubKeyG1() + MOCK_OPERATOR_G2PUBKEY := MOCK_OPERATOR_KEYPAIR.GetPubKeyG2() + + operatorPubkeyDict := map[sdktypes.OperatorId]types.OperatorInfo{ + MOCK_OPERATOR_ID: { + OperatorPubkeys: sdktypes.OperatorPubkeys{ + G1Pubkey: MOCK_OPERATOR_G1PUBKEY, + G2Pubkey: MOCK_OPERATOR_G2PUBKEY, + }, + OperatorAddr: common.Address{}, + }, + } + + aggregator, mockAvsWriterer, mockBlsAggService, err := createMockAggregator(mockCtrl, operatorPubkeyDict) + assert.Nil(t, err) + + var TASK_INDEX = uint32(0) + var BLOCK_NUMBER = uint32(100) + var NUMBER_TO_SQUARE = uint32(3) + var NUMBER_TO_SQUARE_BIG_INT = big.NewInt(int64(NUMBER_TO_SQUARE)) + + mockAvsWriterer.EXPECT().SendNewTaskNumberToSquare( + context.Background(), NUMBER_TO_SQUARE_BIG_INT, types.QUORUM_THRESHOLD_NUMERATOR, types.QUORUM_NUMBERS, + ).Return(mocks.MockSendNewTaskNumberToSquareCall(BLOCK_NUMBER, TASK_INDEX, NUMBER_TO_SQUARE)) + + // 100 blocks, each takes 12 seconds. We hardcode for now since aggregator also hardcodes this value + taskTimeToExpiry := 100 * 12 * time.Second + // make sure that initializeNewTask was called on the blsAggService + // maybe there's a better way to do this? There's a saying "don't mock 3rd party code" + // see https://hynek.me/articles/what-to-mock-in-5-mins/ + mockBlsAggService.EXPECT().InitializeNewTask(TASK_INDEX, BLOCK_NUMBER, types.QUORUM_NUMBERS, sdktypes.QuorumThresholdPercentages{types.QUORUM_THRESHOLD_NUMERATOR}, taskTimeToExpiry) + + err = aggregator.sendNewTask(NUMBER_TO_SQUARE_BIG_INT) + assert.Nil(t, err) +} + +func createMockAggregator( + mockCtrl *gomock.Controller, operatorPubkeyDict map[sdktypes.OperatorId]types.OperatorInfo, +) (*Aggregator, *chainiomocks.MockAvsWriterer, *blsaggservmock.MockBlsAggregationService, error) { + logger := sdklogging.NewNoopLogger() + mockAvsWriter := chainiomocks.NewMockAvsWriterer(mockCtrl) + mockBlsAggregationService := blsaggservmock.NewMockBlsAggregationService(mockCtrl) + + aggregator := &Aggregator{ + logger: logger, + avsWriter: mockAvsWriter, + blsAggregationService: mockBlsAggregationService, + tasks: make(map[types.TaskIndex]cstaskmanager.IIncredibleSquaringTaskManagerTask), + taskResponses: make(map[types.TaskIndex]map[sdktypes.TaskResponseDigest]cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse), + } + return aggregator, mockAvsWriter, mockBlsAggregationService, nil +} + +// just a mock ethclient to pass to bindings +// so that we can access abi methods +func createMockEthClient() *backends.SimulatedBackend { + genesisAlloc := map[common.Address]gethcore.GenesisAccount{} + blockGasLimit := uint64(1000000) + client := backends.NewSimulatedBackend(genesisAlloc, blockGasLimit) + return client +} diff --git a/temp-incredible-squaring-avs/aggregator/cmd/main.go b/temp-incredible-squaring-avs/aggregator/cmd/main.go new file mode 100644 index 0000000..908ffa3 --- /dev/null +++ b/temp-incredible-squaring-avs/aggregator/cmd/main.go @@ -0,0 +1,64 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "log" + "os" + + "github.com/urfave/cli" + + "github.com/Layr-Labs/incredible-squaring-avs/aggregator" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" +) + +var ( + // Version is the version of the binary. + Version string + GitCommit string + GitDate string +) + +func main() { + + app := cli.NewApp() + app.Flags = config.Flags + app.Version = fmt.Sprintf("%s-%s-%s", Version, GitCommit, GitDate) + app.Name = "credible-squaring-aggregator" + app.Usage = "Credible Squaring Aggregator" + app.Description = "Service that sends number to be credibly squared by operator nodes." + + app.Action = aggregatorMain + err := app.Run(os.Args) + if err != nil { + log.Fatalln("Application failed.", "Message:", err) + } +} + +func aggregatorMain(ctx *cli.Context) error { + + log.Println("Initializing Aggregator") + config, err := config.NewConfig(ctx) + if err != nil { + return err + } + configJson, err := json.MarshalIndent(config, "", " ") + if err != nil { + config.Logger.Fatalf(err.Error()) + } + fmt.Println("Config:", string(configJson)) + + agg, err := aggregator.NewAggregator(config) + if err != nil { + return err + } + + err = agg.Start(context.Background()) + if err != nil { + return err + } + + return nil + +} diff --git a/temp-incredible-squaring-avs/aggregator/mocks/chain.go b/temp-incredible-squaring-avs/aggregator/mocks/chain.go new file mode 100644 index 0000000..4bb0730 --- /dev/null +++ b/temp-incredible-squaring-avs/aggregator/mocks/chain.go @@ -0,0 +1,74 @@ +package mocks + +import ( + "math/big" + + opstateretriever "github.com/Layr-Labs/eigensdk-go/contracts/bindings/OperatorStateRetriever" + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + "github.com/Layr-Labs/incredible-squaring-avs/aggregator/types" + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" +) + +// ====== TaskManager Mocks ====== + +func MockSendNewTaskNumberToSquareCall(blockNum, taskNum, numberToSquare uint32) (cstaskmanager.IIncredibleSquaringTaskManagerTask, uint32, error) { + task := cstaskmanager.IIncredibleSquaringTaskManagerTask{ + NumberToBeSquared: big.NewInt(int64(numberToSquare)), + TaskCreatedBlock: blockNum, + QuorumNumbers: types.QUORUM_NUMBERS.UnderlyingType(), + QuorumThresholdPercentage: uint32(types.QUORUM_THRESHOLD_NUMERATOR), + } + + return task, taskNum, nil +} + +// ======= BLSOperatorStateRetriever Mocks ======= +type MockOperatorState struct { + OperatorId [32]byte + Stake *big.Int + G1Pubkey *bls.G1Point + G2Pubkey *bls.G2Point +} +type MockRegistry struct { + OperatorsState []MockOperatorState +} + +func (r *MockRegistry) GetOperatorsId() [][32]byte { + operatorIds := make([][32]byte, len(r.OperatorsState)) + for i, operatorState := range r.OperatorsState { + operatorIds[i] = operatorState.OperatorId + } + return operatorIds +} + +func (r *MockRegistry) GetOperatorsTotalStake() *big.Int { + totalStake := big.NewInt(0) + for _, operatorState := range r.OperatorsState { + totalStake.Add(totalStake, operatorState.Stake) + } + return totalStake +} + +// returns an array of operator states for each quorum number (only [0][] is used since we use a single quorum only) +// currently hardcoded for a single operator +func (r *MockRegistry) MockGetOperatorStateCall() [][]opstateretriever.OperatorStateRetrieverOperator { + quorum0OperatorStakes := make([]opstateretriever.OperatorStateRetrieverOperator, len(r.OperatorsState)) + for i, operatorState := range r.OperatorsState { + quorum0OperatorStakes[i] = opstateretriever.OperatorStateRetrieverOperator{ + OperatorId: operatorState.OperatorId, + Stake: operatorState.Stake, + } + } + return [][]opstateretriever.OperatorStateRetrieverOperator{ + quorum0OperatorStakes, + } +} + +// Aggregates the g1 pubkey of all operators in the mockregistry, assuming they are all registered for quorum0 +func (r *MockRegistry) AggregateG1Pubkey() *bls.G1Point { + aggregateG1Pubkey := bls.NewG1Point(big.NewInt(0), big.NewInt(0)) + for _, operatorState := range r.OperatorsState { + aggregateG1Pubkey.Add(operatorState.G1Pubkey) + } + return aggregateG1Pubkey +} diff --git a/temp-incredible-squaring-avs/aggregator/rpc_server.go b/temp-incredible-squaring-avs/aggregator/rpc_server.go new file mode 100644 index 0000000..c7027bb --- /dev/null +++ b/temp-incredible-squaring-avs/aggregator/rpc_server.go @@ -0,0 +1,72 @@ +package aggregator + +import ( + "context" + "errors" + "net/http" + "net/rpc" + + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + "github.com/Layr-Labs/incredible-squaring-avs/core" + + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + "github.com/Layr-Labs/eigensdk-go/types" + sdktypes "github.com/Layr-Labs/eigensdk-go/types" +) + +var ( + TaskNotFoundError400 = errors.New("400. Task not found") + OperatorNotPartOfTaskQuorum400 = errors.New("400. Operator not part of quorum") + TaskResponseDigestNotFoundError500 = errors.New("500. Failed to get task response digest") + UnknownErrorWhileVerifyingSignature400 = errors.New("400. Failed to verify signature") + SignatureVerificationFailed400 = errors.New("400. Signature verification failed") + CallToGetCheckSignaturesIndicesFailed500 = errors.New("500. Failed to get check signatures indices") +) + +func (agg *Aggregator) startServer(ctx context.Context) error { + + err := rpc.Register(agg) + if err != nil { + agg.logger.Fatal("Format of service TaskManager isn't correct. ", "err", err) + } + rpc.HandleHTTP() + err = http.ListenAndServe(agg.serverIpPortAddr, nil) + if err != nil { + agg.logger.Fatal("ListenAndServe", "err", err) + } + + return nil +} + +type SignedTaskResponse struct { + TaskResponse cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse + BlsSignature bls.Signature + OperatorId types.OperatorId +} + +// rpc endpoint which is called by operator +// reply doesn't need to be checked. If there are no errors, the task response is accepted +// rpc framework forces a reply type to exist, so we put bool as a placeholder +func (agg *Aggregator) ProcessSignedTaskResponse(signedTaskResponse *SignedTaskResponse, reply *bool) error { + agg.logger.Infof("Received signed task response: %#v", signedTaskResponse) + taskIndex := signedTaskResponse.TaskResponse.ReferenceTaskIndex + taskResponseDigest, err := core.GetTaskResponseDigest(&signedTaskResponse.TaskResponse) + if err != nil { + agg.logger.Error("Failed to get task response digest", "err", err) + return TaskResponseDigestNotFoundError500 + } + agg.taskResponsesMu.Lock() + if _, ok := agg.taskResponses[taskIndex]; !ok { + agg.taskResponses[taskIndex] = make(map[sdktypes.TaskResponseDigest]cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse) + } + if _, ok := agg.taskResponses[taskIndex][taskResponseDigest]; !ok { + agg.taskResponses[taskIndex][taskResponseDigest] = signedTaskResponse.TaskResponse + } + agg.taskResponsesMu.Unlock() + + err = agg.blsAggregationService.ProcessNewSignature( + context.Background(), taskIndex, taskResponseDigest, + &signedTaskResponse.BlsSignature, signedTaskResponse.OperatorId, + ) + return err +} diff --git a/temp-incredible-squaring-avs/aggregator/rpc_server_test.go b/temp-incredible-squaring-avs/aggregator/rpc_server_test.go new file mode 100644 index 0000000..6de6c99 --- /dev/null +++ b/temp-incredible-squaring-avs/aggregator/rpc_server_test.go @@ -0,0 +1,81 @@ +package aggregator + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" + + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + sdktypes "github.com/Layr-Labs/eigensdk-go/types" + "github.com/Layr-Labs/incredible-squaring-avs/aggregator/types" + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + "github.com/Layr-Labs/incredible-squaring-avs/core" +) + +func TestProcessSignedTaskResponse(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + var TASK_INDEX = uint32(0) + var BLOCK_NUMBER = uint32(100) + var NUMBER_TO_SQUARE = uint32(3) + + MOCK_OPERATOR_BLS_PRIVATE_KEY, err := bls.NewPrivateKey(MOCK_OPERATOR_BLS_PRIVATE_KEY_STRING) + assert.Nil(t, err) + MOCK_OPERATOR_KEYPAIR := bls.NewKeyPair(MOCK_OPERATOR_BLS_PRIVATE_KEY) + MOCK_OPERATOR_G1PUBKEY := MOCK_OPERATOR_KEYPAIR.GetPubKeyG1() + MOCK_OPERATOR_G2PUBKEY := MOCK_OPERATOR_KEYPAIR.GetPubKeyG2() + + operatorPubkeyDict := map[sdktypes.OperatorId]types.OperatorInfo{ + MOCK_OPERATOR_ID: { + OperatorPubkeys: sdktypes.OperatorPubkeys{ + G1Pubkey: MOCK_OPERATOR_G1PUBKEY, + G2Pubkey: MOCK_OPERATOR_G2PUBKEY, + }, + OperatorAddr: common.Address{}, + }, + } + aggregator, _, mockBlsAggServ, err := createMockAggregator(mockCtrl, operatorPubkeyDict) + assert.Nil(t, err) + + signedTaskResponse, err := createMockSignedTaskResponse(MockTask{ + TaskNum: TASK_INDEX, + BlockNumber: BLOCK_NUMBER, + NumberToSquare: NUMBER_TO_SQUARE, + }, *MOCK_OPERATOR_KEYPAIR) + assert.Nil(t, err) + signedTaskResponseDigest, err := core.GetTaskResponseDigest(&signedTaskResponse.TaskResponse) + assert.Nil(t, err) + + // TODO(samlaf): is this the right way to test writing to external service? + // or is there some wisdom to "don't mock 3rd party code"? + // see https://hynek.me/articles/what-to-mock-in-5-mins/ + mockBlsAggServ.EXPECT().ProcessNewSignature(context.Background(), TASK_INDEX, signedTaskResponseDigest, + &signedTaskResponse.BlsSignature, signedTaskResponse.OperatorId) + err = aggregator.ProcessSignedTaskResponse(signedTaskResponse, nil) + assert.Nil(t, err) +} + +// mocks an operator signing on a task response +func createMockSignedTaskResponse(mockTask MockTask, keypair bls.KeyPair) (*SignedTaskResponse, error) { + numberToSquareBigInt := big.NewInt(int64(mockTask.NumberToSquare)) + taskResponse := &cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse{ + ReferenceTaskIndex: mockTask.TaskNum, + NumberSquared: numberToSquareBigInt.Mul(numberToSquareBigInt, numberToSquareBigInt), + } + taskResponseHash, err := core.GetTaskResponseDigest(taskResponse) + if err != nil { + return nil, err + } + blsSignature := keypair.SignMessage(taskResponseHash) + signedTaskResponse := &SignedTaskResponse{ + TaskResponse: *taskResponse, + BlsSignature: *blsSignature, + OperatorId: MOCK_OPERATOR_ID, + } + return signedTaskResponse, nil +} diff --git a/temp-incredible-squaring-avs/aggregator/types/types.go b/temp-incredible-squaring-avs/aggregator/types/types.go new file mode 100644 index 0000000..174cca7 --- /dev/null +++ b/temp-incredible-squaring-avs/aggregator/types/types.go @@ -0,0 +1,25 @@ +package types + +import ( + sdktypes "github.com/Layr-Labs/eigensdk-go/types" + "github.com/ethereum/go-ethereum/common" +) + +// all operators in quorum0 must sign the task response in order for it to be accepted +// TODO: our contracts require uint8 but right now sdktypes.QuorumThresholdPercentage is uint8 +// prob need to update our inc-sq contracts to use uint8 as well? +const QUORUM_THRESHOLD_NUMERATOR = sdktypes.QuorumThresholdPercentage(100) +const QUORUM_THRESHOLD_DENOMINATOR = sdktypes.QuorumThresholdPercentage(100) + +const QUERY_FILTER_FROM_BLOCK = uint64(1) + +// we only use a single quorum (quorum 0) for incredible squaring +var QUORUM_NUMBERS = sdktypes.QuorumNums{0} + +type BlockNumber = uint32 +type TaskIndex = uint32 + +type OperatorInfo struct { + OperatorPubkeys sdktypes.OperatorPubkeys + OperatorAddr common.Address +} diff --git a/temp-incredible-squaring-avs/challenger/challenger.go b/temp-incredible-squaring-avs/challenger/challenger.go new file mode 100644 index 0000000..0812e91 --- /dev/null +++ b/temp-incredible-squaring-avs/challenger/challenger.go @@ -0,0 +1,242 @@ +package challenger + +import ( + "bytes" + "context" + "math/big" + + ethclient "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" + "github.com/Layr-Labs/eigensdk-go/logging" + "github.com/Layr-Labs/incredible-squaring-avs/common" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" + "github.com/ethereum/go-ethereum/accounts/abi" + + "github.com/Layr-Labs/incredible-squaring-avs/challenger/types" + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + "github.com/Layr-Labs/incredible-squaring-avs/core/chainio" +) + +type Challenger struct { + logger logging.Logger + ethClient ethclient.Client + avsReader chainio.AvsReaderer + avsWriter chainio.AvsWriterer + avsSubscriber chainio.AvsSubscriberer + tasks map[uint32]cstaskmanager.IIncredibleSquaringTaskManagerTask + taskResponses map[uint32]types.TaskResponseData + taskResponseChan chan *cstaskmanager.ContractIncredibleSquaringTaskManagerTaskResponded + newTaskCreatedChan chan *cstaskmanager.ContractIncredibleSquaringTaskManagerNewTaskCreated +} + +func NewChallenger(c *config.Config) (*Challenger, error) { + + avsWriter, err := chainio.BuildAvsWriterFromConfig(c) + if err != nil { + c.Logger.Error("Cannot create EthWriter", "err", err) + return nil, err + } + avsReader, err := chainio.BuildAvsReaderFromConfig(c) + if err != nil { + c.Logger.Error("Cannot create EthReader", "err", err) + return nil, err + } + avsSubscriber, err := chainio.BuildAvsSubscriberFromConfig(c) + if err != nil { + c.Logger.Error("Cannot create EthSubscriber", "err", err) + return nil, err + } + + challenger := &Challenger{ + ethClient: c.EthHttpClient, + logger: c.Logger, + avsWriter: avsWriter, + avsReader: avsReader, + avsSubscriber: avsSubscriber, + tasks: make(map[uint32]cstaskmanager.IIncredibleSquaringTaskManagerTask), + taskResponses: make(map[uint32]types.TaskResponseData), + taskResponseChan: make(chan *cstaskmanager.ContractIncredibleSquaringTaskManagerTaskResponded), + newTaskCreatedChan: make(chan *cstaskmanager.ContractIncredibleSquaringTaskManagerNewTaskCreated), + } + + return challenger, nil +} + +func (c *Challenger) Start(ctx context.Context) error { + c.logger.Infof("Starting Challenger.") + + newTaskSub := c.avsSubscriber.SubscribeToNewTasks(c.newTaskCreatedChan) + c.logger.Infof("Subscribed to new tasks") + + taskResponseSub := c.avsSubscriber.SubscribeToTaskResponses(c.taskResponseChan) + c.logger.Infof("Subscribed to task responses") + + for { + select { + case err := <-newTaskSub.Err(): + // TODO(samlaf): Copied from operator. There was a comment about this on when should exactly do these errors occur? do we need to restart the websocket + c.logger.Error("Error in websocket subscription for new Task", "err", err) + newTaskSub.Unsubscribe() + newTaskSub = c.avsSubscriber.SubscribeToNewTasks(c.newTaskCreatedChan) + + case err := <-taskResponseSub.Err(): + // TODO(samlaf): Copied from operator. There was a comment about this on when should exactly do these errors occur? do we need to restart the websocket + c.logger.Error("Error in websocket subscription for task response", "err", err) + taskResponseSub.Unsubscribe() + taskResponseSub = c.avsSubscriber.SubscribeToTaskResponses(c.taskResponseChan) + + case newTaskCreatedLog := <-c.newTaskCreatedChan: + c.logger.Info("New task created log received", "newTaskCreatedLog", newTaskCreatedLog) + taskIndex := c.processNewTaskCreatedLog(newTaskCreatedLog) + + if _, found := c.taskResponses[taskIndex]; found { + err := c.callChallengeModule(taskIndex) + if err != nil { + c.logger.Error("Error calling challenge module", "err", err) + } + continue + } + + case taskResponseLog := <-c.taskResponseChan: + c.logger.Info("Task response log received", "taskResponseLog", taskResponseLog) + taskIndex := c.processTaskResponseLog(taskResponseLog) + + if _, found := c.tasks[taskIndex]; found { + err := c.callChallengeModule(taskIndex) + if err != nil { + c.logger.Info("Info:", "err", err) + } + continue + } + } + } + +} + +func (c *Challenger) processNewTaskCreatedLog(newTaskCreatedLog *cstaskmanager.ContractIncredibleSquaringTaskManagerNewTaskCreated) uint32 { + c.tasks[newTaskCreatedLog.TaskIndex] = newTaskCreatedLog.Task + return newTaskCreatedLog.TaskIndex +} + +func (c *Challenger) processTaskResponseLog(taskResponseLog *cstaskmanager.ContractIncredibleSquaringTaskManagerTaskResponded) uint32 { + taskResponseRawLog, err := c.avsSubscriber.ParseTaskResponded(taskResponseLog.Raw) + if err != nil { + c.logger.Error("Error parsing task response. skipping task (this is probably bad and should be investigated)", "err", err) + } + + // get the inputs necessary for raising a challenge + nonSigningOperatorPubKeys := c.getNonSigningOperatorPubKeys(taskResponseLog) + taskResponseData := types.TaskResponseData{ + TaskResponse: taskResponseLog.TaskResponse, + TaskResponseMetadata: taskResponseLog.TaskResponseMetadata, + NonSigningOperatorPubKeys: nonSigningOperatorPubKeys, + } + + c.taskResponses[taskResponseRawLog.TaskResponse.ReferenceTaskIndex] = taskResponseData + return taskResponseRawLog.TaskResponse.ReferenceTaskIndex +} + +func (c *Challenger) callChallengeModule(taskIndex uint32) error { + numberToBeSquared := c.tasks[taskIndex].NumberToBeSquared + answerInResponse := c.taskResponses[taskIndex].TaskResponse.NumberSquared + trueAnswer := numberToBeSquared.Exp(numberToBeSquared, big.NewInt(2), nil) + + // checking if the answer in the response submitted by aggregator is correct + if trueAnswer.Cmp(answerInResponse) != 0 { + c.logger.Infof("The number squared is not correct") + + // raise challenge + c.raiseChallenge(taskIndex) + + return nil + } + return types.NoErrorInTaskResponse +} + +func (c *Challenger) getNonSigningOperatorPubKeys(vLog *cstaskmanager.ContractIncredibleSquaringTaskManagerTaskResponded) []cstaskmanager.BN254G1Point { + c.logger.Info("vLog.Raw is", "vLog.Raw", vLog.Raw) + + // get the nonSignerStakesAndSignature + txHash := vLog.Raw.TxHash + c.logger.Info("txHash", "txHash", txHash) + tx, _, err := c.ethClient.TransactionByHash(context.Background(), txHash) + _ = tx + if err != nil { + c.logger.Error("Error getting transaction by hash", + "txHash", txHash, + "err", err, + ) + } + calldata := tx.Data() + c.logger.Info("calldata", "calldata", calldata) + cstmAbi, err := abi.JSON(bytes.NewReader(common.IncredibleSquaringTaskManagerAbi)) + if err != nil { + c.logger.Error("Error getting Abi", "err", err) + } + methodSig := calldata[:4] + c.logger.Info("methodSig", "methodSig", methodSig) + method, err := cstmAbi.MethodById(methodSig) + if err != nil { + c.logger.Error("Error getting method", "err", err) + } + + inputs, err := method.Inputs.Unpack(calldata[4:]) + if err != nil { + c.logger.Error("Error unpacking calldata", "err", err) + } + + nonSignerStakesAndSignatureInput := inputs[2].(struct { + NonSignerQuorumBitmapIndices []uint32 "json:\"nonSignerQuorumBitmapIndices\"" + NonSignerPubkeys []struct { + X *big.Int "json:\"X\"" + Y *big.Int "json:\"Y\"" + } "json:\"nonSignerPubkeys\"" + QuorumApks []struct { + X *big.Int "json:\"X\"" + Y *big.Int "json:\"Y\"" + } "json:\"quorumApks\"" + ApkG2 struct { + X [2]*big.Int "json:\"X\"" + Y [2]*big.Int "json:\"Y\"" + } "json:\"apkG2\"" + Sigma struct { + X *big.Int "json:\"X\"" + Y *big.Int "json:\"Y\"" + } "json:\"sigma\"" + QuorumApkIndices []uint32 "json:\"quorumApkIndices\"" + TotalStakeIndices []uint32 "json:\"totalStakeIndices\"" + NonSignerStakeIndices [][]uint32 "json:\"nonSignerStakeIndices\"" + }) + + // get pubkeys of non-signing operators and submit them to the contract + nonSigningOperatorPubKeys := make([]cstaskmanager.BN254G1Point, len(nonSignerStakesAndSignatureInput.NonSignerPubkeys)) + for i, pubkey := range nonSignerStakesAndSignatureInput.NonSignerPubkeys { + nonSigningOperatorPubKeys[i] = cstaskmanager.BN254G1Point{ + X: pubkey.X, + Y: pubkey.Y, + } + } + + return nonSigningOperatorPubKeys +} + +func (c *Challenger) raiseChallenge(taskIndex uint32) error { + c.logger.Info("Challenger raising challenge.", "taskIndex", taskIndex) + c.logger.Info("Task", "Task", c.tasks[taskIndex]) + c.logger.Info("TaskResponse", "TaskResponse", c.taskResponses[taskIndex].TaskResponse) + c.logger.Info("TaskResponseMetadata", "TaskResponseMetadata", c.taskResponses[taskIndex].TaskResponseMetadata) + c.logger.Info("NonSigningOperatorPubKeys", "NonSigningOperatorPubKeys", c.taskResponses[taskIndex].NonSigningOperatorPubKeys) + + receipt, err := c.avsWriter.RaiseChallenge( + context.Background(), + c.tasks[taskIndex], + c.taskResponses[taskIndex].TaskResponse, + c.taskResponses[taskIndex].TaskResponseMetadata, + c.taskResponses[taskIndex].NonSigningOperatorPubKeys, + ) + if err != nil { + c.logger.Error("Challenger failed to raise challenge:", "err", err) + return err + } + c.logger.Infof("Tx hash of the challenge tx: %v", receipt.TxHash.Hex()) + return nil +} diff --git a/temp-incredible-squaring-avs/challenger/challenger_test.go b/temp-incredible-squaring-avs/challenger/challenger_test.go new file mode 100644 index 0000000..e1447d7 --- /dev/null +++ b/temp-incredible-squaring-avs/challenger/challenger_test.go @@ -0,0 +1,191 @@ +package challenger + +import ( + "context" + "math/big" + "testing" + + mockethclient "github.com/Layr-Labs/eigensdk-go/chainio/mocks" + sdklogging "github.com/Layr-Labs/eigensdk-go/logging" + aggtypes "github.com/Layr-Labs/incredible-squaring-avs/aggregator/types" + "github.com/Layr-Labs/incredible-squaring-avs/challenger/mocks" + chtypes "github.com/Layr-Labs/incredible-squaring-avs/challenger/types" + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + chainiomocks "github.com/Layr-Labs/incredible-squaring-avs/core/chainio/mocks" + "github.com/ethereum/go-ethereum/common" + gethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" +) + +var MOCK_OPERATOR_ID = [32]byte{207, 73, 226, 221, 104, 100, 123, 41, 192, 3, 9, 119, 90, 83, 233, 159, 231, 151, 245, 96, 150, 48, 144, 27, 102, 253, 39, 101, 1, 26, 135, 173} +var MOCK_OPERATOR_STAKE = big.NewInt(100) +var MOCK_OPERATOR_BLS_PRIVATE_KEY_STRING = "50" + +// @samlaf I tried pulling the MockTask struct froma ggregator_test but getting error: "undefined: aggregator.MockTask" +type MockTask struct { + TaskNum uint32 + BlockNumber uint32 + NumberToSquare uint32 +} + +func TestCallChallengeModule(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + challenger, mockAvsWriterer, _, _, _, err := createMockChallenger(mockCtrl) + assert.Nil(t, err) + + const TASK_INDEX = 1 + const BLOCK_NUMBER = uint32(100) + + challenger.tasks[TASK_INDEX] = cstaskmanager.IIncredibleSquaringTaskManagerTask{ + NumberToBeSquared: big.NewInt(3), + TaskCreatedBlock: 1000, + QuorumNumbers: aggtypes.QUORUM_NUMBERS.UnderlyingType(), + QuorumThresholdPercentage: uint32(aggtypes.QUORUM_THRESHOLD_NUMERATOR), + } + + challenger.taskResponses[TASK_INDEX] = chtypes.TaskResponseData{ + TaskResponse: cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse{ + ReferenceTaskIndex: TASK_INDEX, + NumberSquared: big.NewInt(2), + }, + TaskResponseMetadata: cstaskmanager.IIncredibleSquaringTaskManagerTaskResponseMetadata{ + TaskResponsedBlock: 1001, + HashOfNonSigners: [32]byte{}, + }, + NonSigningOperatorPubKeys: []cstaskmanager.BN254G1Point{}, + } + + mockAvsWriterer.EXPECT().RaiseChallenge( + context.Background(), + challenger.tasks[TASK_INDEX], + challenger.taskResponses[TASK_INDEX].TaskResponse, + challenger.taskResponses[TASK_INDEX].TaskResponseMetadata, + challenger.taskResponses[TASK_INDEX].NonSigningOperatorPubKeys, + ).Return(mocks.MockRaiseAndResolveChallengeCall(BLOCK_NUMBER, TASK_INDEX), nil) + + msg := challenger.callChallengeModule(TASK_INDEX) + assert.Equal(t, msg, nil) + +} + +func TestRaiseChallenge(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + challenger, mockAvsWriterer, _, _, _, err := createMockChallenger(mockCtrl) + assert.Nil(t, err) + + const TASK_INDEX = 1 + const BLOCK_NUMBER = uint32(100) + + challenger.tasks[TASK_INDEX] = cstaskmanager.IIncredibleSquaringTaskManagerTask{ + NumberToBeSquared: big.NewInt(3), + TaskCreatedBlock: 1000, + QuorumNumbers: aggtypes.QUORUM_NUMBERS.UnderlyingType(), + QuorumThresholdPercentage: uint32(aggtypes.QUORUM_THRESHOLD_NUMERATOR), + } + + challenger.taskResponses[TASK_INDEX] = chtypes.TaskResponseData{ + TaskResponse: cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse{ + ReferenceTaskIndex: TASK_INDEX, + NumberSquared: big.NewInt(9), + }, + TaskResponseMetadata: cstaskmanager.IIncredibleSquaringTaskManagerTaskResponseMetadata{ + TaskResponsedBlock: 1001, + HashOfNonSigners: [32]byte{}, + }, + NonSigningOperatorPubKeys: []cstaskmanager.BN254G1Point{}, + } + + mockAvsWriterer.EXPECT().RaiseChallenge( + context.Background(), + challenger.tasks[TASK_INDEX], + challenger.taskResponses[TASK_INDEX].TaskResponse, + challenger.taskResponses[TASK_INDEX].TaskResponseMetadata, + challenger.taskResponses[TASK_INDEX].NonSigningOperatorPubKeys, + ).Return(mocks.MockRaiseAndResolveChallengeCall(BLOCK_NUMBER, TASK_INDEX), nil) + + err = challenger.raiseChallenge(TASK_INDEX) + assert.Nil(t, err) +} + +func TestProcessTaskResponseLog(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + challenger, _, _, mockAvsSubscriber, mockEthClient, err := createMockChallenger(mockCtrl) + assert.Nil(t, err) + + const TASK_INDEX = 1 + + challenger.tasks[TASK_INDEX] = cstaskmanager.IIncredibleSquaringTaskManagerTask{ + NumberToBeSquared: big.NewInt(3), + TaskCreatedBlock: 1000, + QuorumNumbers: aggtypes.QUORUM_NUMBERS.UnderlyingType(), + QuorumThresholdPercentage: uint32(aggtypes.QUORUM_THRESHOLD_NUMERATOR), + } + + challenger.taskResponses[TASK_INDEX] = chtypes.TaskResponseData{ + TaskResponse: cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse{ + ReferenceTaskIndex: TASK_INDEX, + NumberSquared: big.NewInt(9), + }, + TaskResponseMetadata: cstaskmanager.IIncredibleSquaringTaskManagerTaskResponseMetadata{ + TaskResponsedBlock: 1001, + HashOfNonSigners: [32]byte{}, + }, + NonSigningOperatorPubKeys: []cstaskmanager.BN254G1Point{}, + } + + taskResponseLog := cstaskmanager.ContractIncredibleSquaringTaskManagerTaskResponded{ + TaskResponse: challenger.taskResponses[TASK_INDEX].TaskResponse, + TaskResponseMetadata: challenger.taskResponses[TASK_INDEX].TaskResponseMetadata, + Raw: gethtypes.Log{ + Address: common.HexToAddress("0x9e545e3c0baab3e08cdfd552c960a1050f373042"), + Topics: []common.Hash{ + // this is the actual TaskChallengedSuccessfully event from calling the func "raiseAndResolveChallenge" + common.HexToHash("0x349c1ee60e4e8972ee9dba642c1774543d5c4136879b7f4caaf04bf81a487a2a"), + }, + Data: common.Hex2Bytes("0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a50fe07922f57ae3b4553201bfd7c11aca85e1541f91db8e62dca9c418dc5feae"), + BlockNumber: uint64(100), + TxHash: common.HexToHash("0x6d3b7741fef7cfb22d943cb1c3d221b71253acdf7e56925969d54a18a8566480"), + TxIndex: 1, + BlockHash: common.HexToHash("0x0"), + Index: 1, + Removed: false, + }, + } + + mockAvsSubscriber.EXPECT().ParseTaskResponded(taskResponseLog.Raw).Return(&taskResponseLog, nil) + + mockEthClient.EXPECT().TransactionByHash( + context.Background(), taskResponseLog.Raw.TxHash, + ).Return(mocks.MockTransactionByHash(), true, nil) + + taskIndex := challenger.processTaskResponseLog(&taskResponseLog) + assert.Equal(t, taskIndex, uint32(TASK_INDEX)) + +} + +func createMockChallenger(mockCtrl *gomock.Controller) (*Challenger, *chainiomocks.MockAvsWriterer, *chainiomocks.MockAvsReaderer, *chainiomocks.MockAvsSubscriberer, *mockethclient.MockEthClient, error) { + logger := sdklogging.NewNoopLogger() + mockAvsWriter := chainiomocks.NewMockAvsWriterer(mockCtrl) + mockAvsReader := chainiomocks.NewMockAvsReaderer(mockCtrl) + mockAvsSubscriber := chainiomocks.NewMockAvsSubscriberer(mockCtrl) + mockEthClient := mockethclient.NewMockEthClient(mockCtrl) + challenger := &Challenger{ + logger: logger, + avsWriter: mockAvsWriter, + avsReader: mockAvsReader, + ethClient: mockEthClient, + avsSubscriber: mockAvsSubscriber, + tasks: make(map[uint32]cstaskmanager.IIncredibleSquaringTaskManagerTask), + taskResponses: make(map[uint32]chtypes.TaskResponseData), + taskResponseChan: make(chan *cstaskmanager.ContractIncredibleSquaringTaskManagerTaskResponded), + newTaskCreatedChan: make(chan *cstaskmanager.ContractIncredibleSquaringTaskManagerNewTaskCreated), + } + return challenger, mockAvsWriter, mockAvsReader, mockAvsSubscriber, mockEthClient, nil +} diff --git a/temp-incredible-squaring-avs/challenger/cmd/main.go b/temp-incredible-squaring-avs/challenger/cmd/main.go new file mode 100644 index 0000000..9f964a1 --- /dev/null +++ b/temp-incredible-squaring-avs/challenger/cmd/main.go @@ -0,0 +1,64 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "log" + "os" + + "github.com/urfave/cli" + + "github.com/Layr-Labs/incredible-squaring-avs/challenger" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" +) + +var ( + // Version is the version of the binary. + Version string + GitCommit string + GitDate string +) + +func main() { + + app := cli.NewApp() + app.Flags = config.Flags + app.Version = fmt.Sprintf("%s-%s-%s", Version, GitCommit, GitDate) + app.Name = "credible-squaring-challenger" + app.Usage = "Credible Squaring Challenger" + app.Description = "Service that challenges wrong response to the task." + + app.Action = challengerMain + err := app.Run(os.Args) + if err != nil { + log.Fatalln("Application failed.", "Message:", err) + } +} + +func challengerMain(ctx *cli.Context) error { + + log.Println("Initializing Challenger...") + config, err := config.NewConfig(ctx) + if err != nil { + return err + } + configJson, err := json.MarshalIndent(config, "", " ") + if err != nil { + config.Logger.Fatalf(err.Error()) + } + fmt.Println("Config:", string(configJson)) + + chal, err := challenger.NewChallenger(config) + if err != nil { + return err + } + + err = chal.Start(context.Background()) + if err != nil { + return err + } + + return nil + +} diff --git a/temp-incredible-squaring-avs/challenger/mocks/chain.go b/temp-incredible-squaring-avs/challenger/mocks/chain.go new file mode 100644 index 0000000..3e83b08 --- /dev/null +++ b/temp-incredible-squaring-avs/challenger/mocks/chain.go @@ -0,0 +1,81 @@ +package mocks + +import ( + "encoding/hex" + "math/big" + + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + "github.com/ethereum/go-ethereum/common" + gethtypes "github.com/ethereum/go-ethereum/core/types" +) + +func MockTransactionByHash() *gethtypes.Transaction { + // This is the calldata that is obtained from having only one operator participating in the AVS with a pubkey we choose + // in our setting and is behaving maliciously. + // This calldata was obtained by printing the "RespondToTask" transation and copying the calldata from the logs. + input, err := hex.DecodeString("5baec9a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001c00bcb2b68b6c68a5aea7fe75b5446c4ca410461fa226c2487d07eb2c504639cb52a3b3f7ef4f62985af31809fdc531483e5f1cd67aa1bcf0f8ac0d17e158aa9670940e64478db51fe630cc540dbeabea34d072a54fd7c743056e18174f9a1b64e00c874e4fcfb88d5c98a0240bc6f7f37d45f2226ca147317b3a2b7243ddb6c1b18b8fa707217c86c152f2ec3824f7de662a7c51d3bdf1c20ad574282dde7e6b30ddcb5a696413e8e02e318ae10dadd07c53822ed6832c97f8923d9f38f55b5170000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010b5c664a181b916702c1acbbe4617a673cf9fffe733ff902353e315e11f9a7c11bd3ff011ee7d19e9d2ceef4475aac85313e8f31e4b8c66114d32e4ef0ee99590000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000") + if err != nil { + panic(err) + } + baseTx := &gethtypes.DynamicFeeTx{ + Data: input, + } + + return gethtypes.NewTx(baseTx) +} + +func MockRaiseAndResolveChallengeCall(blockNum, taskNum uint32) *gethtypes.Receipt { + return &gethtypes.Receipt{ + Type: 1, + PostState: []byte{}, + Status: 0, + CumulativeGasUsed: 1000000, + Bloom: gethtypes.Bloom{}, + Logs: []*gethtypes.Log{ + { + Address: common.HexToAddress("0xeb61b2307b5846f9e0a72eece51d9cba88256683"), + Topics: []common.Hash{ + // this is the actual TaskChallengedSuccessfully event from calling the func "raiseAndResolveChallenge" + common.HexToHash("0xc20d1bb0f1623680306b83d4ff4bb99a2beb9d86d97832f3ca40fd13a29df1ec"), + common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001"), + common.HexToHash("0x0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc"), + }, + Data: []byte{}, + BlockNumber: uint64(blockNum), + TxHash: common.HexToHash("0x0"), + TxIndex: 1, + BlockHash: common.HexToHash("0x0"), + Index: 1, + Removed: false, + }, + }, + TxHash: common.HexToHash("0x0"), + ContractAddress: common.HexToAddress("0x0"), + GasUsed: 0, + EffectiveGasPrice: big.NewInt(int64(blockNum)), + BlockHash: common.HexToHash("0x0"), + BlockNumber: big.NewInt(int64(blockNum)), + TransactionIndex: 1, + } +} + +func MockTaskResponseLog() gethtypes.Log { + return gethtypes.Log{ + Address: common.HexToAddress("0x9e545e3c0baab3e08cdfd552c960a1050f373042"), + Topics: []common.Hash{ + // this is the actual TaskChallengedSuccessfully event from calling the func "raiseAndResolveChallenge" + common.HexToHash("0x349c1ee60e4e8972ee9dba642c1774543d5c4136879b7f4caaf04bf81a487a2a"), + }, + Data: common.Hex2Bytes("0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a50fe07922f57ae3b4553201bfd7c11aca85e1541f91db8e62dca9c418dc5feae"), + BlockNumber: uint64(100), + TxHash: common.HexToHash("0x0"), + TxIndex: 1, + BlockHash: common.HexToHash("0x0"), + Index: 1, + Removed: false, + } +} + +func MockTaskResponseReferenceTaskIndex(taskResponse cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse) uint32 { + return taskResponse.ReferenceTaskIndex +} diff --git a/temp-incredible-squaring-avs/challenger/types/types.go b/temp-incredible-squaring-avs/challenger/types/types.go new file mode 100644 index 0000000..a86f1f0 --- /dev/null +++ b/temp-incredible-squaring-avs/challenger/types/types.go @@ -0,0 +1,17 @@ +package types + +import ( + "errors" + + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" +) + +type TaskResponseData struct { + TaskResponse cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse + TaskResponseMetadata cstaskmanager.IIncredibleSquaringTaskManagerTaskResponseMetadata + NonSigningOperatorPubKeys []cstaskmanager.BN254G1Point +} + +var ( + NoErrorInTaskResponse = errors.New("100. Task response is valid") +) diff --git a/temp-incredible-squaring-avs/cli/actions/deposit_into_strategy.go b/temp-incredible-squaring-avs/cli/actions/deposit_into_strategy.go new file mode 100644 index 0000000..0ccf9bd --- /dev/null +++ b/temp-incredible-squaring-avs/cli/actions/deposit_into_strategy.go @@ -0,0 +1,54 @@ +package actions + +import ( + "encoding/json" + "fmt" + "log" + "math/big" + + sdkutils "github.com/Layr-Labs/eigensdk-go/utils" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" + "github.com/Layr-Labs/incredible-squaring-avs/operator" + "github.com/Layr-Labs/incredible-squaring-avs/types" + "github.com/ethereum/go-ethereum/common" + "github.com/urfave/cli" +) + +func DepositIntoStrategy(ctx *cli.Context) error { + + configPath := ctx.GlobalString(config.ConfigFileFlag.Name) + nodeConfig := types.NodeConfig{} + err := sdkutils.ReadYamlConfig(configPath, &nodeConfig) + if err != nil { + return err + } + // need to make sure we don't register the operator on startup + // when using the cli commands to register the operator. + nodeConfig.RegisterOperatorOnStartup = false + configJson, err := json.MarshalIndent(nodeConfig, "", " ") + if err != nil { + log.Fatalf(err.Error()) + } + log.Println("Config:", string(configJson)) + + operator, err := operator.NewOperatorFromConfig(nodeConfig) + if err != nil { + return err + } + + strategyAddrStr := ctx.String("strategy-addr") + strategyAddr := common.HexToAddress(strategyAddrStr) + amountStr := ctx.String("amount") + amount, ok := new(big.Int).SetString(amountStr, 10) + if !ok { + fmt.Println("Error converting amount to big.Int") + return err + } + + err = operator.DepositIntoStrategy(strategyAddr, amount) + if err != nil { + return err + } + + return nil +} diff --git a/temp-incredible-squaring-avs/cli/actions/print_operator_status.go b/temp-incredible-squaring-avs/cli/actions/print_operator_status.go new file mode 100644 index 0000000..88bdcf9 --- /dev/null +++ b/temp-incredible-squaring-avs/cli/actions/print_operator_status.go @@ -0,0 +1,42 @@ +package actions + +import ( + "encoding/json" + "log" + + sdkutils "github.com/Layr-Labs/eigensdk-go/utils" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" + "github.com/Layr-Labs/incredible-squaring-avs/operator" + "github.com/Layr-Labs/incredible-squaring-avs/types" + "github.com/urfave/cli" +) + +func PrintOperatorStatus(ctx *cli.Context) error { + + configPath := ctx.GlobalString(config.ConfigFileFlag.Name) + nodeConfig := types.NodeConfig{} + err := sdkutils.ReadYamlConfig(configPath, &nodeConfig) + if err != nil { + return err + } + // need to make sure we don't register the operator on startup + // when using the cli commands to register the operator. + nodeConfig.RegisterOperatorOnStartup = false + configJson, err := json.MarshalIndent(nodeConfig, "", " ") + if err != nil { + log.Fatalf(err.Error()) + } + log.Println("Config:", string(configJson)) + + operator, err := operator.NewOperatorFromConfig(nodeConfig) + if err != nil { + return err + } + + err = operator.PrintOperatorStatus() + if err != nil { + return err + } + + return nil +} diff --git a/temp-incredible-squaring-avs/cli/actions/register_operator_with_avs.go b/temp-incredible-squaring-avs/cli/actions/register_operator_with_avs.go new file mode 100644 index 0000000..e2a1934 --- /dev/null +++ b/temp-incredible-squaring-avs/cli/actions/register_operator_with_avs.go @@ -0,0 +1,56 @@ +package actions + +import ( + "encoding/json" + "log" + "os" + + sdkecdsa "github.com/Layr-Labs/eigensdk-go/crypto/ecdsa" + sdkutils "github.com/Layr-Labs/eigensdk-go/utils" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" + "github.com/Layr-Labs/incredible-squaring-avs/operator" + "github.com/Layr-Labs/incredible-squaring-avs/types" + "github.com/urfave/cli" +) + +func RegisterOperatorWithAvs(ctx *cli.Context) error { + + configPath := ctx.GlobalString(config.ConfigFileFlag.Name) + nodeConfig := types.NodeConfig{} + err := sdkutils.ReadYamlConfig(configPath, &nodeConfig) + if err != nil { + return err + } + // need to make sure we don't register the operator on startup + // when using the cli commands to register the operator. + nodeConfig.RegisterOperatorOnStartup = false + configJson, err := json.MarshalIndent(nodeConfig, "", " ") + if err != nil { + log.Fatalf(err.Error()) + } + log.Println("Config:", string(configJson)) + + operator, err := operator.NewOperatorFromConfig(nodeConfig) + if err != nil { + return err + } + + ecdsaKeyPassword, ok := os.LookupEnv("OPERATOR_ECDSA_KEY_PASSWORD") + if !ok { + log.Printf("OPERATOR_ECDSA_KEY_PASSWORD env var not set. using empty string") + } + operatorEcdsaPrivKey, err := sdkecdsa.ReadKey( + nodeConfig.EcdsaPrivateKeyStorePath, + ecdsaKeyPassword, + ) + if err != nil { + return err + } + + err = operator.RegisterOperatorWithAvs(operatorEcdsaPrivKey) + if err != nil { + return err + } + + return nil +} diff --git a/temp-incredible-squaring-avs/cli/actions/register_operator_with_eigenlayer.go b/temp-incredible-squaring-avs/cli/actions/register_operator_with_eigenlayer.go new file mode 100644 index 0000000..53ff313 --- /dev/null +++ b/temp-incredible-squaring-avs/cli/actions/register_operator_with_eigenlayer.go @@ -0,0 +1,42 @@ +package actions + +import ( + "encoding/json" + "github.com/urfave/cli" + "log" + + sdkutils "github.com/Layr-Labs/eigensdk-go/utils" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" + "github.com/Layr-Labs/incredible-squaring-avs/operator" + "github.com/Layr-Labs/incredible-squaring-avs/types" +) + +func RegisterOperatorWithEigenlayer(ctx *cli.Context) error { + + configPath := ctx.GlobalString(config.ConfigFileFlag.Name) + nodeConfig := types.NodeConfig{} + err := sdkutils.ReadYamlConfig(configPath, &nodeConfig) + if err != nil { + return err + } + // need to make sure we don't register the operator on startup + // when using the cli commands to register the operator. + nodeConfig.RegisterOperatorOnStartup = false + configJson, err := json.MarshalIndent(nodeConfig, "", " ") + if err != nil { + log.Fatalf(err.Error()) + } + log.Println("Config:", string(configJson)) + + operator, err := operator.NewOperatorFromConfig(nodeConfig) + if err != nil { + return err + } + + err = operator.RegisterOperatorWithEigenlayer() + if err != nil { + return err + } + + return nil +} diff --git a/temp-incredible-squaring-avs/cli/main.go b/temp-incredible-squaring-avs/cli/main.go new file mode 100644 index 0000000..60bf109 --- /dev/null +++ b/temp-incredible-squaring-avs/cli/main.go @@ -0,0 +1,67 @@ +package main + +import ( + "log" + "os" + + "github.com/Layr-Labs/incredible-squaring-avs/cli/actions" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" + "github.com/urfave/cli" +) + +func main() { + app := cli.NewApp() + + app.Flags = []cli.Flag{config.ConfigFileFlag} + app.Commands = []cli.Command{ + { + Name: "register-operator-with-eigenlayer", + Aliases: []string{"rel"}, + Usage: "registers operator with eigenlayer (this should be called via eigenlayer cli, not plugin, but keeping here for convenience for now)", + Action: actions.RegisterOperatorWithEigenlayer, + }, + { + Name: "deposit-into-strategy", + Aliases: []string{"d"}, + Usage: "deposit tokens into a strategy", + Action: actions.DepositIntoStrategy, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "strategy-addr", + Usage: "Address of Strategy contract to deposit into", + Required: true, + }, + cli.StringFlag{ + Name: "amount", + Usage: "amount of tokens to deposit into strategy", + Required: true, + }, + }, + }, + { + Name: "register-operator-with-avs", + Aliases: []string{"r"}, + Usage: "registers bls keys with pubkey-compendium, opts into slashing by avs service-manager, and registers operators with avs registry", + Action: actions.RegisterOperatorWithAvs, + }, + { + Name: "deregister-operator-with-avs", + Aliases: []string{"d"}, + Action: func(ctx *cli.Context) error { + log.Fatal("Command not implemented.") + return nil + }, + }, + { + Name: "print-operator-status", + Aliases: []string{"s"}, + Usage: "prints operator status as viewed from incredible squaring contracts", + Action: actions.PrintOperatorStatus, + }, + } + + err := app.Run(os.Args) + if err != nil { + log.Fatal(err) + } +} diff --git a/temp-incredible-squaring-avs/common/abi.go b/temp-incredible-squaring-avs/common/abi.go new file mode 100644 index 0000000..c93fe15 --- /dev/null +++ b/temp-incredible-squaring-avs/common/abi.go @@ -0,0 +1,8 @@ +package common + +import ( + _ "embed" +) + +//go:embed abis/IncredibleSquaringTaskManager.json +var IncredibleSquaringTaskManagerAbi []byte diff --git a/temp-incredible-squaring-avs/common/abis/IncredibleSquaringTaskManager.json b/temp-incredible-squaring-avs/common/abis/IncredibleSquaringTaskManager.json new file mode 100644 index 0000000..ce896da --- /dev/null +++ b/temp-incredible-squaring-avs/common/abis/IncredibleSquaringTaskManager.json @@ -0,0 +1,1198 @@ +[ + { + "inputs": [ + { + "internalType": "contract IBLSRegistryCoordinatorWithIndices", + "name": "_registryCoordinator", + "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": "uint32", + "name": "taskIndex", + "type": "uint32" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "numberToBeSquared", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "taskCreatedBlock", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "quorumNumbers", + "type": "bytes" + }, + { + "internalType": "uint32", + "name": "quorumThresholdPercentage", + "type": "uint32" + } + ], + "indexed": true, + "internalType": "struct IIncredibleSquaringTaskManager.Task", + "name": "task", + "type": "tuple" + } + ], + "name": "NewTaskCreated", + "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": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPausedStatus", + "type": "uint256" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IPauserRegistry", + "name": "pauserRegistry", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IPauserRegistry", + "name": "newPauserRegistry", + "type": "address" + } + ], + "name": "PauserRegistrySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "taskIndex", + "type": "uint32" + }, + { + "indexed": true, + "internalType": "address", + "name": "challenger", + "type": "address" + } + ], + "name": "TaskChallengedSuccessfully", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "taskIndex", + "type": "uint32" + }, + { + "indexed": true, + "internalType": "address", + "name": "challenger", + "type": "address" + } + ], + "name": "TaskChallengedUnsuccessfully", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint32", + "name": "taskIndex", + "type": "uint32" + } + ], + "name": "TaskCompleted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "referenceTaskIndex", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "numberSquared", + "type": "uint256" + } + ], + "indexed": true, + "internalType": "struct IIncredibleSquaringTaskManager.TaskResponse", + "name": "taskResponse", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "taskResponsedBlock", + "type": "uint32" + }, + { + "internalType": "bytes32", + "name": "hashOfNonSigners", + "type": "bytes32" + } + ], + "indexed": true, + "internalType": "struct IIncredibleSquaringTaskManager.TaskResponseMetadata", + "name": "taskResponseMetadata", + "type": "tuple" + } + ], + "name": "TaskResponded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newPausedStatus", + "type": "uint256" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "TASK_CHALLENGE_WINDOW_BLOCK", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TASK_RESPONSE_WINDOW_BLOCK", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "aggregator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "blsPubkeyRegistry", + "outputs": [ + { + "internalType": "contract IBLSPubkeyRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "quorumNumbers", + "type": "bytes" + }, + { + "internalType": "uint32", + "name": "referenceBlockNumber", + "type": "uint32" + }, + { + "components": [ + { + "internalType": "uint32[]", + "name": "nonSignerQuorumBitmapIndices", + "type": "uint32[]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "X", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "Y", + "type": "uint256" + } + ], + "internalType": "struct BN254.G1Point[]", + "name": "nonSignerPubkeys", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "X", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "Y", + "type": "uint256" + } + ], + "internalType": "struct BN254.G1Point[]", + "name": "quorumApks", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256[2]", + "name": "X", + "type": "uint256[2]" + }, + { + "internalType": "uint256[2]", + "name": "Y", + "type": "uint256[2]" + } + ], + "internalType": "struct BN254.G2Point", + "name": "apkG2", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "X", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "Y", + "type": "uint256" + } + ], + "internalType": "struct BN254.G1Point", + "name": "sigma", + "type": "tuple" + }, + { + "internalType": "uint32[]", + "name": "quorumApkIndices", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "totalStakeIndices", + "type": "uint32[]" + }, + { + "internalType": "uint32[][]", + "name": "nonSignerStakeIndices", + "type": "uint32[][]" + } + ], + "internalType": "struct BLSSignatureChecker.NonSignerStakesAndSignature", + "name": "nonSignerStakesAndSignature", + "type": "tuple" + } + ], + "name": "checkSignatures", + "outputs": [ + { + "components": [ + { + "internalType": "uint96[]", + "name": "signedStakeForQuorum", + "type": "uint96[]" + }, + { + "internalType": "uint96[]", + "name": "totalStakeForQuorum", + "type": "uint96[]" + } + ], + "internalType": "struct BLSSignatureChecker.QuorumStakeTotals", + "name": "", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "numberToBeSquared", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "quorumThresholdPercentage", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "quorumNumbers", + "type": "bytes" + } + ], + "name": "createNewTask", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "generator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBLSRegistryCoordinatorWithIndices", + "name": "registryCoordinator", + "type": "address" + }, + { + "internalType": "uint32", + "name": "referenceBlockNumber", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "quorumNumbers", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "nonSignerOperatorIds", + "type": "bytes32[]" + } + ], + "name": "getCheckSignaturesIndices", + "outputs": [ + { + "components": [ + { + "internalType": "uint32[]", + "name": "nonSignerQuorumBitmapIndices", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "quorumApkIndices", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "totalStakeIndices", + "type": "uint32[]" + }, + { + "internalType": "uint32[][]", + "name": "nonSignerStakeIndices", + "type": "uint32[][]" + } + ], + "internalType": "struct BLSOperatorStateRetriever.CheckSignaturesIndices", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBLSRegistryCoordinatorWithIndices", + "name": "registryCoordinator", + "type": "address" + }, + { + "internalType": "bytes", + "name": "quorumNumbers", + "type": "bytes" + }, + { + "internalType": "uint32", + "name": "blockNumber", + "type": "uint32" + } + ], + "name": "getOperatorPubkeys", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "operatorId", + "type": "bytes32" + }, + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "X", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "Y", + "type": "uint256" + } + ], + "internalType": "struct BN254.G1Point", + "name": "pubkeyG1", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256[2]", + "name": "X", + "type": "uint256[2]" + }, + { + "internalType": "uint256[2]", + "name": "Y", + "type": "uint256[2]" + } + ], + "internalType": "struct BN254.G2Point", + "name": "pubkeyG2", + "type": "tuple" + } + ], + "internalType": "struct IBLSPublicKeyCompendium.BN254Pubkeys", + "name": "bn254pubkeys", + "type": "tuple" + } + ], + "internalType": "struct BLSOperatorStateRetriever.OperatorPubkeys[][]", + "name": "", + "type": "tuple[][]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBLSRegistryCoordinatorWithIndices", + "name": "registryCoordinator", + "type": "address" + }, + { + "internalType": "bytes", + "name": "quorumNumbers", + "type": "bytes" + }, + { + "internalType": "uint32", + "name": "blockNumber", + "type": "uint32" + } + ], + "name": "getOperatorState", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "operatorId", + "type": "bytes32" + }, + { + "internalType": "uint96", + "name": "stake", + "type": "uint96" + } + ], + "internalType": "struct BLSOperatorStateRetriever.Operator[][]", + "name": "", + "type": "tuple[][]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IBLSRegistryCoordinatorWithIndices", + "name": "registryCoordinator", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "operatorId", + "type": "bytes32" + }, + { + "internalType": "uint32", + "name": "blockNumber", + "type": "uint32" + } + ], + "name": "getOperatorState", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "operatorId", + "type": "bytes32" + }, + { + "internalType": "uint96", + "name": "stake", + "type": "uint96" + } + ], + "internalType": "struct BLSOperatorStateRetriever.Operator[][]", + "name": "", + "type": "tuple[][]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IPauserRegistry", + "name": "_pauserRegistry", + "type": "address" + }, + { + "internalType": "address", + "name": "initialOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "_aggregator", + "type": "address" + }, + { + "internalType": "address", + "name": "_generator", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "latestTaskNum", + "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": "uint256", + "name": "newPausedStatus", + "type": "uint256" + } + ], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pauseAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "index", + "type": "uint8" + } + ], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauserRegistry", + "outputs": [ + { + "internalType": "contract IPauserRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "numberToBeSquared", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "taskCreatedBlock", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "quorumNumbers", + "type": "bytes" + }, + { + "internalType": "uint32", + "name": "quorumThresholdPercentage", + "type": "uint32" + } + ], + "internalType": "struct IIncredibleSquaringTaskManager.Task", + "name": "task", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "referenceTaskIndex", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "numberSquared", + "type": "uint256" + } + ], + "internalType": "struct IIncredibleSquaringTaskManager.TaskResponse", + "name": "taskResponse", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "taskResponsedBlock", + "type": "uint32" + }, + { + "internalType": "bytes32", + "name": "hashOfNonSigners", + "type": "bytes32" + } + ], + "internalType": "struct IIncredibleSquaringTaskManager.TaskResponseMetadata", + "name": "taskResponseMetadata", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "X", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "Y", + "type": "uint256" + } + ], + "internalType": "struct BN254.G1Point[]", + "name": "pubkeysOfNonSigningOperators", + "type": "tuple[]" + } + ], + "name": "raiseAndResolveChallenge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "registryCoordinator", + "outputs": [ + { + "internalType": "contract IRegistryCoordinator", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "numberToBeSquared", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "taskCreatedBlock", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "quorumNumbers", + "type": "bytes" + }, + { + "internalType": "uint32", + "name": "quorumThresholdPercentage", + "type": "uint32" + } + ], + "internalType": "struct IIncredibleSquaringTaskManager.Task", + "name": "task", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "referenceTaskIndex", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "numberSquared", + "type": "uint256" + } + ], + "internalType": "struct IIncredibleSquaringTaskManager.TaskResponse", + "name": "taskResponse", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint32[]", + "name": "nonSignerQuorumBitmapIndices", + "type": "uint32[]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "X", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "Y", + "type": "uint256" + } + ], + "internalType": "struct BN254.G1Point[]", + "name": "nonSignerPubkeys", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "X", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "Y", + "type": "uint256" + } + ], + "internalType": "struct BN254.G1Point[]", + "name": "quorumApks", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256[2]", + "name": "X", + "type": "uint256[2]" + }, + { + "internalType": "uint256[2]", + "name": "Y", + "type": "uint256[2]" + } + ], + "internalType": "struct BN254.G2Point", + "name": "apkG2", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "X", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "Y", + "type": "uint256" + } + ], + "internalType": "struct BN254.G1Point", + "name": "sigma", + "type": "tuple" + }, + { + "internalType": "uint32[]", + "name": "quorumApkIndices", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "totalStakeIndices", + "type": "uint32[]" + }, + { + "internalType": "uint32[][]", + "name": "nonSignerStakeIndices", + "type": "uint32[][]" + } + ], + "internalType": "struct BLSSignatureChecker.NonSignerStakesAndSignature", + "name": "nonSignerStakesAndSignature", + "type": "tuple" + } + ], + "name": "respondToTask", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IPauserRegistry", + "name": "newPauserRegistry", + "type": "address" + } + ], + "name": "setPauserRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stakeRegistry", + "outputs": [ + { + "internalType": "contract IStakeRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "taskNumber", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "X", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "Y", + "type": "uint256" + } + ], + "internalType": "struct BN254.G1Point", + "name": "apk", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256[2]", + "name": "X", + "type": "uint256[2]" + }, + { + "internalType": "uint256[2]", + "name": "Y", + "type": "uint256[2]" + } + ], + "internalType": "struct BN254.G2Point", + "name": "apkG2", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "X", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "Y", + "type": "uint256" + } + ], + "internalType": "struct BN254.G1Point", + "name": "sigma", + "type": "tuple" + } + ], + "name": "trySignatureAndApkVerification", + "outputs": [ + { + "internalType": "bool", + "name": "pairingSuccessful", + "type": "bool" + }, + { + "internalType": "bool", + "name": "siganatureIsValid", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newPausedStatus", + "type": "uint256" + } + ], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/temp-incredible-squaring-avs/config-files/aggregator-docker-compose.yaml b/temp-incredible-squaring-avs/config-files/aggregator-docker-compose.yaml new file mode 100644 index 0000000..49d18a4 --- /dev/null +++ b/temp-incredible-squaring-avs/config-files/aggregator-docker-compose.yaml @@ -0,0 +1,6 @@ +# production only prints info and above. development also prints debug +environment: production +eth_rpc_url: http://anvil:8545 +eth_ws_url: ws://anvil:8545 +# address which the aggregator listens on for operator signed messages +aggregator_server_ip_port_address: 0.0.0.0:8090 \ No newline at end of file diff --git a/temp-incredible-squaring-avs/config-files/aggregator.yaml b/temp-incredible-squaring-avs/config-files/aggregator.yaml new file mode 100644 index 0000000..74adba2 --- /dev/null +++ b/temp-incredible-squaring-avs/config-files/aggregator.yaml @@ -0,0 +1,6 @@ +# 'production' only prints info and above. 'development' also prints debug +environment: production +eth_rpc_url: http://localhost:8545 +eth_ws_url: ws://localhost:8545 +# address which the aggregator listens on for operator signed messages +aggregator_server_ip_port_address: localhost:8090 diff --git a/temp-incredible-squaring-avs/config-files/challenger.yaml b/temp-incredible-squaring-avs/config-files/challenger.yaml new file mode 100644 index 0000000..52af8f3 --- /dev/null +++ b/temp-incredible-squaring-avs/config-files/challenger.yaml @@ -0,0 +1,4 @@ +# 'production' only prints info and above. 'development' also prints debug +environment: production +eth_rpc_url: http://localhost:8545 +eth_ws_url: ws://localhost:8545 diff --git a/temp-incredible-squaring-avs/config-files/operator-docker-compose.anvil.yaml b/temp-incredible-squaring-avs/config-files/operator-docker-compose.anvil.yaml new file mode 100644 index 0000000..46242e9 --- /dev/null +++ b/temp-incredible-squaring-avs/config-files/operator-docker-compose.anvil.yaml @@ -0,0 +1,49 @@ +# this sets the logger level (true = info, false = debug) +production: false + +operator_address: 0x860B6912C2d0337ef05bbC89b0C2CB6CbAEAB4A5 + +# EigenLayer Slasher contract address + +# This is the address of the contracts which are deployed in the anvil saved state +# The saved eigenlayer state is located in tests/anvil/credible_squaring_avs_deployment_output.json +# TODO(samlaf): automate updating these addresses when we deploy new contracts +avs_registry_coordinator_address: 0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9 +operator_state_retriever_address: 0x95401dc811bb5740090279Ba06cfA8fcF6113778 + +# ETH RPC URL +eth_rpc_url: http://anvil:8545 +eth_ws_url: ws://anvil:8545 + +# If you running this using eigenlayer CLI and the provided AVS packaging structure, +# this should be /operator_keys/ecdsa_key.json as the host path will be asked while running +# +# If you are running locally using go run main.go, this should be full path to your local ecdsa key file +ecdsa_private_key_store_path: tests/keys/test.ecdsa.key.json + +# If you running this using eigenlayer CLI and the provided AVS packaging structure, +# this should be /operator_keys/bls_key.json as the host path will be asked while running +# +# We are using bn254 curve for bls keys +# +# If you are running locally using go run main.go, this should be full path to your local bls key file +bls_private_key_store_path: tests/keys/test.bls.key.json + +# address which the aggregator listens on for operator signed messages +aggregator_server_ip_port_address: incredible-squaring-aggregator:8090 + +# avs node spec compliance https://eigen.nethermind.io/docs/spec/intro +eigen_metrics_ip_port_address: 0.0.0.0:9090 +enable_metrics: true +node_api_ip_port_address: 0.0.0.0:9010 +enable_node_api: true + +# we need to register the operator on startup when running the docker compose file +# because unfortunately we cannot register the operator previously and save it in the anvil json file +# This is because anvil only dumps the state, and not the receipt tree, so when we restart anvil with +# the registered operator, it's blspubkey registering event with the compendium is not present anymore, +# and so the aggregator can't find it.... very annoying +register_operator_on_startup: true +# address of token to deposit tokens into when registering on startup +# addresses.erc20MockStrategy in tests/anvil/credible_squaring_avs_deployment_output.json +token_strategy_addr: 0x09635F643e140090A9A8Dcd712eD6285858ceBef \ No newline at end of file diff --git a/temp-incredible-squaring-avs/config-files/operator.anvil.yaml b/temp-incredible-squaring-avs/config-files/operator.anvil.yaml new file mode 100644 index 0000000..5365ba8 --- /dev/null +++ b/temp-incredible-squaring-avs/config-files/operator.anvil.yaml @@ -0,0 +1,44 @@ +# this sets the logger level (true = info, false = debug) +production: true + +operator_address: 0x860B6912C2d0337ef05bbC89b0C2CB6CbAEAB4A5 + +# EigenLayer Slasher contract address + +# This is the address of the contracts which are deployed in the anvil saved state +# The saved eigenlayer state is located in tests/anvil/credible_squaring_avs_deployment_output.json +# TODO(samlaf): automate updating these addresses when we deploy new contracts +avs_registry_coordinator_address: 0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9 +operator_state_retriever_address: 0x95401dc811bb5740090279Ba06cfA8fcF6113778 + +# ETH RPC URL +eth_rpc_url: http://localhost:8545 +eth_ws_url: ws://localhost:8545 + +# If you running this using eigenlayer CLI and the provided AVS packaging structure, +# this should be /operator_keys/ecdsa_key.json as the host path will be asked while running +# +# If you are running locally using go run main.go, this should be full path to your local ecdsa key file +ecdsa_private_key_store_path: tests/keys/test.ecdsa.key.json + +# If you running this using eigenlayer CLI and the provided AVS packaging structure, +# this should be /operator_keys/bls_key.json as the host path will be asked while running +# +# We are using bn254 curve for bls keys +# +# If you are running locally using go run main.go, this should be full path to your local bls key file +bls_private_key_store_path: tests/keys/test.bls.key.json + +# address which the aggregator listens on for operator signed messages +aggregator_server_ip_port_address: localhost:8090 + +# avs node spec compliance https://eigen.nethermind.io/docs/spec/intro +eigen_metrics_ip_port_address: localhost:9090 +enable_metrics: true +node_api_ip_port_address: localhost:9010 +enable_node_api: true + +register_operator_on_startup: true +# address of token to deposit tokens into when registering on startup +# addresses.erc20MockStrategy in tests/anvil/credible_squaring_avs_deployment_output.json +token_strategy_addr: 0x09635F643e140090A9A8Dcd712eD6285858ceBef diff --git a/temp-incredible-squaring-avs/contracts/.github/workflows/test.yml b/temp-incredible-squaring-avs/contracts/.github/workflows/test.yml new file mode 100644 index 0000000..09880b1 --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/.github/workflows/test.yml @@ -0,0 +1,34 @@ +name: test + +on: workflow_dispatch + +env: + FOUNDRY_PROFILE: ci + +jobs: + check: + strategy: + fail-fast: true + + name: Foundry project + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Run Forge build + run: | + forge --version + forge build --sizes + id: build + + - name: Run Forge tests + run: | + forge test -vvv + id: test diff --git a/temp-incredible-squaring-avs/contracts/.gitignore b/temp-incredible-squaring-avs/contracts/.gitignore new file mode 100644 index 0000000..cd9278d --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/.gitignore @@ -0,0 +1,15 @@ +# Compiler files +cache/ +out/ + +# Ignores development broadcast logs +/broadcast/** + +# Docs +docs/ + +# Dotenv file +.env + +# Not sure what this folder is for.. so removing for now +data/ diff --git a/temp-incredible-squaring-avs/contracts/README.md b/temp-incredible-squaring-avs/contracts/README.md new file mode 100644 index 0000000..9265b45 --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/README.md @@ -0,0 +1,66 @@ +## Foundry + +**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** + +Foundry consists of: + +- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). +- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. +- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. +- **Chisel**: Fast, utilitarian, and verbose solidity REPL. + +## Documentation + +https://book.getfoundry.sh/ + +## Usage + +### Build + +```shell +$ forge build +``` + +### Test + +```shell +$ forge test +``` + +### Format + +```shell +$ forge fmt +``` + +### Gas Snapshots + +```shell +$ forge snapshot +``` + +### Anvil + +```shell +$ anvil +``` + +### Deploy + +```shell +$ forge script script/Counter.s.sol:CounterScript --rpc-url --private-key +``` + +### Cast + +```shell +$ cast +``` + +### Help + +```shell +$ forge --help +$ anvil --help +$ cast --help +``` diff --git a/temp-incredible-squaring-avs/contracts/bindings/ERC20Mock/binding.go b/temp-incredible-squaring-avs/contracts/bindings/ERC20Mock/binding.go new file mode 100644 index 0000000..bd3f1af --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/bindings/ERC20Mock/binding.go @@ -0,0 +1,688 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contractERC20Mock + +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 + _ = abi.ConvertType +) + +// ContractERC20MockMetaData contains all meta data concerning the ContractERC20Mock contract. +var ContractERC20MockMetaData = &bind.MetaData{ + ABI: "[{\"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\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"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\":\"mint\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"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: "0x608060405234801561001057600080fd5b50610527806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c806340c10f191161005b57806340c10f19146100d257806370a08231146100e7578063a9059cbb14610110578063dd62ed3e1461012357600080fd5b8063095ea7b31461008257806318160ddd146100ad57806323b872dd146100bf575b600080fd5b610098610090366004610410565b600192915050565b60405190151581526020015b60405180910390f35b6002545b6040519081526020016100a4565b6100986100cd36600461043a565b61015c565b6100e56100e0366004610410565b610173565b005b6100b16100f5366004610476565b6001600160a01b031660009081526020819052604090205490565b61009861011e366004610410565b610181565b6100b1610131366004610498565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600061016984848461018b565b5060019392505050565b61017d8282610335565b5050565b6000336101698185855b6001600160a01b0383166101f45760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084015b60405180910390fd5b6001600160a01b0382166102565760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016101eb565b6001600160a01b0383166000908152602081905260409020548111156102cd5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016101eb565b6001600160a01b038381166000818152602081815260408083208054879003905593861680835291849020805486019055925184815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6001600160a01b03821661038b5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016101eb565b806002600082825461039d91906104cb565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b80356001600160a01b038116811461040b57600080fd5b919050565b6000806040838503121561042357600080fd5b61042c836103f4565b946020939093013593505050565b60008060006060848603121561044f57600080fd5b610458846103f4565b9250610466602085016103f4565b9150604084013590509250925092565b60006020828403121561048857600080fd5b610491826103f4565b9392505050565b600080604083850312156104ab57600080fd5b6104b4836103f4565b91506104c2602084016103f4565b90509250929050565b600082198211156104ec57634e487b7160e01b600052601160045260246000fd5b50019056fea26469706673582212200c8f4a0047ca0322c22cf7e6a789abbe36ca3141cd508f864ec741dccdc347f964736f6c634300080c0033", +} + +// ContractERC20MockABI is the input ABI used to generate the binding from. +// Deprecated: Use ContractERC20MockMetaData.ABI instead. +var ContractERC20MockABI = ContractERC20MockMetaData.ABI + +// ContractERC20MockBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ContractERC20MockMetaData.Bin instead. +var ContractERC20MockBin = ContractERC20MockMetaData.Bin + +// DeployContractERC20Mock deploys a new Ethereum contract, binding an instance of ContractERC20Mock to it. +func DeployContractERC20Mock(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ContractERC20Mock, error) { + parsed, err := ContractERC20MockMetaData.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(ContractERC20MockBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ContractERC20Mock{ContractERC20MockCaller: ContractERC20MockCaller{contract: contract}, ContractERC20MockTransactor: ContractERC20MockTransactor{contract: contract}, ContractERC20MockFilterer: ContractERC20MockFilterer{contract: contract}}, nil +} + +// ContractERC20Mock is an auto generated Go binding around an Ethereum contract. +type ContractERC20Mock struct { + ContractERC20MockCaller // Read-only binding to the contract + ContractERC20MockTransactor // Write-only binding to the contract + ContractERC20MockFilterer // Log filterer for contract events +} + +// ContractERC20MockCaller is an auto generated read-only Go binding around an Ethereum contract. +type ContractERC20MockCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractERC20MockTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ContractERC20MockTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractERC20MockFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ContractERC20MockFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractERC20MockSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ContractERC20MockSession struct { + Contract *ContractERC20Mock // 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 +} + +// ContractERC20MockCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ContractERC20MockCallerSession struct { + Contract *ContractERC20MockCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ContractERC20MockTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ContractERC20MockTransactorSession struct { + Contract *ContractERC20MockTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ContractERC20MockRaw is an auto generated low-level Go binding around an Ethereum contract. +type ContractERC20MockRaw struct { + Contract *ContractERC20Mock // Generic contract binding to access the raw methods on +} + +// ContractERC20MockCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ContractERC20MockCallerRaw struct { + Contract *ContractERC20MockCaller // Generic read-only contract binding to access the raw methods on +} + +// ContractERC20MockTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ContractERC20MockTransactorRaw struct { + Contract *ContractERC20MockTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewContractERC20Mock creates a new instance of ContractERC20Mock, bound to a specific deployed contract. +func NewContractERC20Mock(address common.Address, backend bind.ContractBackend) (*ContractERC20Mock, error) { + contract, err := bindContractERC20Mock(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ContractERC20Mock{ContractERC20MockCaller: ContractERC20MockCaller{contract: contract}, ContractERC20MockTransactor: ContractERC20MockTransactor{contract: contract}, ContractERC20MockFilterer: ContractERC20MockFilterer{contract: contract}}, nil +} + +// NewContractERC20MockCaller creates a new read-only instance of ContractERC20Mock, bound to a specific deployed contract. +func NewContractERC20MockCaller(address common.Address, caller bind.ContractCaller) (*ContractERC20MockCaller, error) { + contract, err := bindContractERC20Mock(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ContractERC20MockCaller{contract: contract}, nil +} + +// NewContractERC20MockTransactor creates a new write-only instance of ContractERC20Mock, bound to a specific deployed contract. +func NewContractERC20MockTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractERC20MockTransactor, error) { + contract, err := bindContractERC20Mock(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ContractERC20MockTransactor{contract: contract}, nil +} + +// NewContractERC20MockFilterer creates a new log filterer instance of ContractERC20Mock, bound to a specific deployed contract. +func NewContractERC20MockFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractERC20MockFilterer, error) { + contract, err := bindContractERC20Mock(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ContractERC20MockFilterer{contract: contract}, nil +} + +// bindContractERC20Mock binds a generic wrapper to an already deployed contract. +func bindContractERC20Mock(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ContractERC20MockMetaData.GetAbi() + 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 (_ContractERC20Mock *ContractERC20MockRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ContractERC20Mock.Contract.ContractERC20MockCaller.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 (_ContractERC20Mock *ContractERC20MockRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractERC20Mock.Contract.ContractERC20MockTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ContractERC20Mock *ContractERC20MockRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ContractERC20Mock.Contract.ContractERC20MockTransactor.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 (_ContractERC20Mock *ContractERC20MockCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ContractERC20Mock.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 (_ContractERC20Mock *ContractERC20MockTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractERC20Mock.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ContractERC20Mock *ContractERC20MockTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ContractERC20Mock.Contract.contract.Transact(opts, method, params...) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_ContractERC20Mock *ContractERC20MockCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _ContractERC20Mock.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 (_ContractERC20Mock *ContractERC20MockSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _ContractERC20Mock.Contract.Allowance(&_ContractERC20Mock.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 (_ContractERC20Mock *ContractERC20MockCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _ContractERC20Mock.Contract.Allowance(&_ContractERC20Mock.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ContractERC20Mock *ContractERC20MockCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _ContractERC20Mock.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 (_ContractERC20Mock *ContractERC20MockSession) BalanceOf(account common.Address) (*big.Int, error) { + return _ContractERC20Mock.Contract.BalanceOf(&_ContractERC20Mock.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_ContractERC20Mock *ContractERC20MockCallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _ContractERC20Mock.Contract.BalanceOf(&_ContractERC20Mock.CallOpts, account) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ContractERC20Mock *ContractERC20MockCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ContractERC20Mock.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 (_ContractERC20Mock *ContractERC20MockSession) TotalSupply() (*big.Int, error) { + return _ContractERC20Mock.Contract.TotalSupply(&_ContractERC20Mock.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_ContractERC20Mock *ContractERC20MockCallerSession) TotalSupply() (*big.Int, error) { + return _ContractERC20Mock.Contract.TotalSupply(&_ContractERC20Mock.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address , uint256 ) returns(bool) +func (_ContractERC20Mock *ContractERC20MockTransactor) Approve(opts *bind.TransactOpts, arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { + return _ContractERC20Mock.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 (_ContractERC20Mock *ContractERC20MockSession) Approve(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { + return _ContractERC20Mock.Contract.Approve(&_ContractERC20Mock.TransactOpts, arg0, arg1) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address , uint256 ) returns(bool) +func (_ContractERC20Mock *ContractERC20MockTransactorSession) Approve(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { + return _ContractERC20Mock.Contract.Approve(&_ContractERC20Mock.TransactOpts, arg0, arg1) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 amount) returns() +func (_ContractERC20Mock *ContractERC20MockTransactor) Mint(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _ContractERC20Mock.contract.Transact(opts, "mint", account, amount) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 amount) returns() +func (_ContractERC20Mock *ContractERC20MockSession) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _ContractERC20Mock.Contract.Mint(&_ContractERC20Mock.TransactOpts, account, amount) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 amount) returns() +func (_ContractERC20Mock *ContractERC20MockTransactorSession) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _ContractERC20Mock.Contract.Mint(&_ContractERC20Mock.TransactOpts, account, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 amount) returns(bool) +func (_ContractERC20Mock *ContractERC20MockTransactor) Transfer(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _ContractERC20Mock.contract.Transact(opts, "transfer", to, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 amount) returns(bool) +func (_ContractERC20Mock *ContractERC20MockSession) Transfer(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _ContractERC20Mock.Contract.Transfer(&_ContractERC20Mock.TransactOpts, to, amount) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 amount) returns(bool) +func (_ContractERC20Mock *ContractERC20MockTransactorSession) Transfer(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _ContractERC20Mock.Contract.Transfer(&_ContractERC20Mock.TransactOpts, to, amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 amount) returns(bool) +func (_ContractERC20Mock *ContractERC20MockTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _ContractERC20Mock.contract.Transact(opts, "transferFrom", from, to, amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 amount) returns(bool) +func (_ContractERC20Mock *ContractERC20MockSession) TransferFrom(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _ContractERC20Mock.Contract.TransferFrom(&_ContractERC20Mock.TransactOpts, from, to, amount) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 amount) returns(bool) +func (_ContractERC20Mock *ContractERC20MockTransactorSession) TransferFrom(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _ContractERC20Mock.Contract.TransferFrom(&_ContractERC20Mock.TransactOpts, from, to, amount) +} + +// ContractERC20MockApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the ContractERC20Mock contract. +type ContractERC20MockApprovalIterator struct { + Event *ContractERC20MockApproval // 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 *ContractERC20MockApprovalIterator) 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(ContractERC20MockApproval) + 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(ContractERC20MockApproval) + 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 *ContractERC20MockApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractERC20MockApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractERC20MockApproval represents a Approval event raised by the ContractERC20Mock contract. +type ContractERC20MockApproval 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 (_ContractERC20Mock *ContractERC20MockFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*ContractERC20MockApprovalIterator, 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 := _ContractERC20Mock.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &ContractERC20MockApprovalIterator{contract: _ContractERC20Mock.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 (_ContractERC20Mock *ContractERC20MockFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *ContractERC20MockApproval, 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 := _ContractERC20Mock.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(ContractERC20MockApproval) + if err := _ContractERC20Mock.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 (_ContractERC20Mock *ContractERC20MockFilterer) ParseApproval(log types.Log) (*ContractERC20MockApproval, error) { + event := new(ContractERC20MockApproval) + if err := _ContractERC20Mock.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractERC20MockTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the ContractERC20Mock contract. +type ContractERC20MockTransferIterator struct { + Event *ContractERC20MockTransfer // 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 *ContractERC20MockTransferIterator) 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(ContractERC20MockTransfer) + 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(ContractERC20MockTransfer) + 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 *ContractERC20MockTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractERC20MockTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractERC20MockTransfer represents a Transfer event raised by the ContractERC20Mock contract. +type ContractERC20MockTransfer 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 (_ContractERC20Mock *ContractERC20MockFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*ContractERC20MockTransferIterator, 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 := _ContractERC20Mock.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &ContractERC20MockTransferIterator{contract: _ContractERC20Mock.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 (_ContractERC20Mock *ContractERC20MockFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *ContractERC20MockTransfer, 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 := _ContractERC20Mock.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(ContractERC20MockTransfer) + if err := _ContractERC20Mock.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 (_ContractERC20Mock *ContractERC20MockFilterer) ParseTransfer(log types.Log) (*ContractERC20MockTransfer, error) { + event := new(ContractERC20MockTransfer) + if err := _ContractERC20Mock.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/temp-incredible-squaring-avs/contracts/bindings/IncredibleSquaringServiceManager/binding.go b/temp-incredible-squaring-avs/contracts/bindings/IncredibleSquaringServiceManager/binding.go new file mode 100644 index 0000000..3cb870d --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/bindings/IncredibleSquaringServiceManager/binding.go @@ -0,0 +1,814 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contractIncredibleSquaringServiceManager + +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 + _ = abi.ConvertType +) + +// IPaymentCoordinatorRangePayment is an auto generated low-level Go binding around an user-defined struct. +type IPaymentCoordinatorRangePayment struct { + StrategiesAndMultipliers []IPaymentCoordinatorStrategyAndMultiplier + Token common.Address + Amount *big.Int + StartTimestamp uint32 + Duration uint32 +} + +// IPaymentCoordinatorStrategyAndMultiplier is an auto generated low-level Go binding around an user-defined struct. +type IPaymentCoordinatorStrategyAndMultiplier struct { + Strategy common.Address + Multiplier *big.Int +} + +// ISignatureUtilsSignatureWithSaltAndExpiry is an auto generated low-level Go binding around an user-defined struct. +type ISignatureUtilsSignatureWithSaltAndExpiry struct { + Signature []byte + Salt [32]byte + Expiry *big.Int +} + +// ContractIncredibleSquaringServiceManagerMetaData contains all meta data concerning the ContractIncredibleSquaringServiceManager contract. +var ContractIncredibleSquaringServiceManagerMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_avsDirectory\",\"type\":\"address\",\"internalType\":\"contractIAVSDirectory\"},{\"name\":\"_registryCoordinator\",\"type\":\"address\",\"internalType\":\"contractIRegistryCoordinator\"},{\"name\":\"_stakeRegistry\",\"type\":\"address\",\"internalType\":\"contractIStakeRegistry\"},{\"name\":\"_incredibleSquaringTaskManager\",\"type\":\"address\",\"internalType\":\"contractIIncredibleSquaringTaskManager\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"avsDirectory\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deregisterOperatorFromAVS\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"freezeOperator\",\"inputs\":[{\"name\":\"operatorAddr\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getOperatorRestakedStrategies\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRestakeableStrategies\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"incredibleSquaringTaskManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIIncredibleSquaringTaskManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"payForRange\",\"inputs\":[{\"name\":\"rangePayments\",\"type\":\"tuple[]\",\"internalType\":\"structIPaymentCoordinator.RangePayment[]\",\"components\":[{\"name\":\"strategiesAndMultipliers\",\"type\":\"tuple[]\",\"internalType\":\"structIPaymentCoordinator.StrategyAndMultiplier[]\",\"components\":[{\"name\":\"strategy\",\"type\":\"address\",\"internalType\":\"contractIStrategy\"},{\"name\":\"multiplier\",\"type\":\"uint96\",\"internalType\":\"uint96\"}]},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startTimestamp\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"duration\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"registerOperatorToAVS\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorSignature\",\"type\":\"tuple\",\"internalType\":\"structISignatureUtils.SignatureWithSaltAndExpiry\",\"components\":[{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"salt\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"expiry\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAVSMetadataURI\",\"inputs\":[{\"name\":\"_metadataURI\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"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: "0x6101206040523480156200001257600080fd5b5060405162001b5f38038062001b5f83398101604081905262000035916200015a565b6001600160a01b03808516608052600060a081905281851660c05290831660e05284908484620000646200007f565b505050506001600160a01b03166101005250620001c2915050565b600054610100900460ff1615620000ec5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811610156200013f576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6001600160a01b03811681146200015757600080fd5b50565b600080600080608085870312156200017157600080fd5b84516200017e8162000141565b6020860151909450620001918162000141565b6040860151909350620001a48162000141565b6060860151909250620001b78162000141565b939692955090935050565b60805160a05160c05160e051610100516118e86200027760003960008181610151015261093b01526000818161065a015281816107b60152818161084d01528181610c7601528181610dfa0152610e99015260008181610485015281816105140152818161059401528181610a0801528181610a9e01528181610bb40152610d5501526000818161031501526103f301526000818161010c01528181610a5c01528181610afa0152610b7901526118e86000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80638da5cb5b116100715780638da5cb5b146101735780639926ee7d14610184578063a364f4da14610197578063a98fb355146101aa578063e481af9d146101bd578063f2fde38b146101c557600080fd5b80631b445516146100b957806333cfb7b7146100ce57806338c8ee64146100f75780636b3aa72e1461010a578063715018a61461014457806377ef731d1461014c575b600080fd5b6100cc6100c736600461118e565b6101d8565b005b6100e16100dc366004611218565b610460565b6040516100ee919061123c565b60405180910390f35b6100cc610105366004611218565b610930565b7f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b0390911681526020016100ee565b6100cc6109e9565b61012c7f000000000000000000000000000000000000000000000000000000000000000081565b6033546001600160a01b031661012c565b6100cc61019236600461133e565b6109fd565b6100cc6101a5366004611218565b610a93565b6100cc6101b83660046113e9565b610b5a565b6100e1610bae565b6100cc6101d3366004611218565b610f78565b6101e0610fee565b60005b818110156103db578282828181106101fd576101fd61143a565b905060200281019061020f9190611450565b610220906040810190602001611218565b6001600160a01b03166323b872dd33308686868181106102425761024261143a565b90506020028101906102549190611450565b604080516001600160e01b031960e087901b1681526001600160a01b039485166004820152939092166024840152013560448201526064016020604051808303816000875af11580156102ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102cf9190611480565b508282828181106102e2576102e261143a565b90506020028101906102f49190611450565b610305906040810190602001611218565b6001600160a01b031663095ea7b37f00000000000000000000000000000000000000000000000000000000000000008585858181106103465761034661143a565b90506020028101906103589190611450565b604080516001600160e01b031960e086901b1681526001600160a01b039093166004840152013560248201526044016020604051808303816000875af11580156103a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ca9190611480565b506103d4816114b8565b90506101e3565b50604051630da22a8b60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631b4455169061042a908590859060040161156c565b600060405180830381600087803b15801561044457600080fd5b505af1158015610458573d6000803e3d6000fd5b505050505050565b6040516309aa152760e11b81526001600160a01b0382811660048301526060916000917f000000000000000000000000000000000000000000000000000000000000000016906313542a4e90602401602060405180830381865afa1580156104cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f0919061167a565b60405163871ef04960e01b8152600481018290529091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063871ef04990602401602060405180830381865afa15801561055b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057f9190611693565b90506001600160c01b038116158061061957507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639aa1653d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061491906116bc565b60ff16155b1561063557505060408051600081526020810190915292915050565b6000610649826001600160c01b0316611048565b90506000805b825181101561071f577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633ca5a5f58483815181106106995761069961143a565b01602001516040516001600160e01b031960e084901b16815260f89190911c6004820152602401602060405180830381865afa1580156106dd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610701919061167a565b61070b90836116df565b915080610717816114b8565b91505061064f565b5060008167ffffffffffffffff81111561073b5761073b611289565b604051908082528060200260200182016040528015610764578160200160208202803683370190505b5090506000805b84518110156109235760008582815181106107885761078861143a565b0160200151604051633ca5a5f560e01b815260f89190911c6004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633ca5a5f590602401602060405180830381865afa1580156107fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610821919061167a565b905060005b8181101561090d576040516356e4026d60e11b815260ff84166004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063adc804da906044016040805180830381865afa15801561089b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf91906116f7565b600001518686815181106108d5576108d561143a565b6001600160a01b0390921660209283029190910190910152846108f7816114b8565b9550508080610905906114b8565b915050610826565b505050808061091b906114b8565b91505061076b565b5090979650505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109e65760405162461bcd60e51b815260206004820152604a60248201527f6f6e6c79496e6372656469626c655371756172696e675461736b4d616e61676560448201527f723a206e6f742066726f6d206372656469626c65207371756172696e6720746160648201526939b59036b0b730b3b2b960b11b608482015260a4015b60405180910390fd5b50565b6109f1610fee565b6109fb600061110b565b565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a455760405162461bcd60e51b81526004016109dd90611756565b604051639926ee7d60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690639926ee7d9061042a908590859060040161181b565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610adb5760405162461bcd60e51b81526004016109dd90611756565b6040516351b27a6d60e11b81526001600160a01b0382811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063a364f4da906024015b600060405180830381600087803b158015610b3f57600080fd5b505af1158015610b53573d6000803e3d6000fd5b5050505050565b610b62610fee565b60405163a98fb35560e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a98fb35590610b25908490600401611866565b606060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639aa1653d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3491906116bc565b60ff16905080610c5257505060408051600081526020810190915290565b6000805b82811015610d0757604051633ca5a5f560e01b815260ff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690633ca5a5f590602401602060405180830381865afa158015610cc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce9919061167a565b610cf390836116df565b915080610cff816114b8565b915050610c56565b5060008167ffffffffffffffff811115610d2357610d23611289565b604051908082528060200260200182016040528015610d4c578160200160208202803683370190505b5090506000805b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639aa1653d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610db1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd591906116bc565b60ff16811015610f6e57604051633ca5a5f560e01b815260ff821660048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690633ca5a5f590602401602060405180830381865afa158015610e49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6d919061167a565b905060005b81811015610f59576040516356e4026d60e11b815260ff84166004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063adc804da906044016040805180830381865afa158015610ee7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0b91906116f7565b60000151858581518110610f2157610f2161143a565b6001600160a01b039092166020928302919091019091015283610f43816114b8565b9450508080610f51906114b8565b915050610e72565b50508080610f66906114b8565b915050610d53565b5090949350505050565b610f80610fee565b6001600160a01b038116610fe55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109dd565b6109e68161110b565b6033546001600160a01b031633146109fb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109dd565b60606000806110568461115d565b61ffff1667ffffffffffffffff81111561107257611072611289565b6040519080825280601f01601f19166020018201604052801561109c576020820181803683370190505b5090506000805b8251821080156110b4575061010081105b15610f6e576001811b9350858416156110fb578060f81b8383815181106110dd576110dd61143a565b60200101906001600160f81b031916908160001a9053508160010191505b611104816114b8565b90506110a3565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000805b821561118857611172600184611879565b909216918061118081611890565b915050611161565b92915050565b600080602083850312156111a157600080fd5b823567ffffffffffffffff808211156111b957600080fd5b818501915085601f8301126111cd57600080fd5b8135818111156111dc57600080fd5b8660208260051b85010111156111f157600080fd5b60209290920196919550909350505050565b6001600160a01b03811681146109e657600080fd5b60006020828403121561122a57600080fd5b813561123581611203565b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561127d5783516001600160a01b031683529284019291840191600101611258565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156112c2576112c2611289565b60405290565b600067ffffffffffffffff808411156112e3576112e3611289565b604051601f8501601f19908116603f0116810190828211818310171561130b5761130b611289565b8160405280935085815286868601111561132457600080fd5b858560208301376000602087830101525050509392505050565b6000806040838503121561135157600080fd5b823561135c81611203565b9150602083013567ffffffffffffffff8082111561137957600080fd5b908401906060828703121561138d57600080fd5b61139561129f565b8235828111156113a457600080fd5b83019150601f820187136113b757600080fd5b6113c6878335602085016112c8565b815260208301356020820152604083013560408201528093505050509250929050565b6000602082840312156113fb57600080fd5b813567ffffffffffffffff81111561141257600080fd5b8201601f8101841361142357600080fd5b611432848235602084016112c8565b949350505050565b634e487b7160e01b600052603260045260246000fd5b60008235609e1983360301811261146657600080fd5b9190910192915050565b803561147b81611203565b919050565b60006020828403121561149257600080fd5b8151801515811461123557600080fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156114cc576114cc6114a2565b5060010190565b6bffffffffffffffffffffffff811681146109e657600080fd5b8183526000602080850194508260005b8581101561154d57813561151081611203565b6001600160a01b0316875281830135611528816114d3565b6bffffffffffffffffffffffff168784015260409687019691909101906001016114fd565b509495945050505050565b803563ffffffff8116811461147b57600080fd5b60208082528181018390526000906040808401600586901b8501820187855b8881101561166c57878303603f190184528135368b9003609e190181126115b157600080fd5b8a0160a0813536839003601e190181126115ca57600080fd5b8201803567ffffffffffffffff8111156115e357600080fd5b8060061b36038413156115f557600080fd5b828752611607838801828c85016114ed565b92505050611616888301611470565b6001600160a01b03168886015281870135878601526060611638818401611558565b63ffffffff1690860152608061164f838201611558565b63ffffffff1695019490945250928501929085019060010161158b565b509098975050505050505050565b60006020828403121561168c57600080fd5b5051919050565b6000602082840312156116a557600080fd5b81516001600160c01b038116811461123557600080fd5b6000602082840312156116ce57600080fd5b815160ff8116811461123557600080fd5b600082198211156116f2576116f26114a2565b500190565b60006040828403121561170957600080fd5b6040516040810181811067ffffffffffffffff8211171561172c5761172c611289565b604052825161173a81611203565b8152602083015161174a816114d3565b60208201529392505050565b60208082526052908201527f536572766963654d616e61676572426173652e6f6e6c7952656769737472794360408201527f6f6f7264696e61746f723a2063616c6c6572206973206e6f742074686520726560608201527133b4b9ba393c9031b7b7b93234b730ba37b960711b608082015260a00190565b6000815180845260005b818110156117f4576020818501810151868301820152016117d8565b81811115611806576000602083870101525b50601f01601f19169290920160200192915050565b60018060a01b038316815260406020820152600082516060604084015261184560a08401826117ce565b90506020840151606084015260408401516080840152809150509392505050565b60208152600061123560208301846117ce565b60008282101561188b5761188b6114a2565b500390565b600061ffff808316818114156118a8576118a86114a2565b600101939250505056fea2646970667358221220939ffbc2731160a3acf904aa502ec683052f07166493f46f16b3d34f23164d3664736f6c634300080c0033", +} + +// ContractIncredibleSquaringServiceManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use ContractIncredibleSquaringServiceManagerMetaData.ABI instead. +var ContractIncredibleSquaringServiceManagerABI = ContractIncredibleSquaringServiceManagerMetaData.ABI + +// ContractIncredibleSquaringServiceManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ContractIncredibleSquaringServiceManagerMetaData.Bin instead. +var ContractIncredibleSquaringServiceManagerBin = ContractIncredibleSquaringServiceManagerMetaData.Bin + +// DeployContractIncredibleSquaringServiceManager deploys a new Ethereum contract, binding an instance of ContractIncredibleSquaringServiceManager to it. +func DeployContractIncredibleSquaringServiceManager(auth *bind.TransactOpts, backend bind.ContractBackend, _avsDirectory common.Address, _registryCoordinator common.Address, _stakeRegistry common.Address, _incredibleSquaringTaskManager common.Address) (common.Address, *types.Transaction, *ContractIncredibleSquaringServiceManager, error) { + parsed, err := ContractIncredibleSquaringServiceManagerMetaData.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(ContractIncredibleSquaringServiceManagerBin), backend, _avsDirectory, _registryCoordinator, _stakeRegistry, _incredibleSquaringTaskManager) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ContractIncredibleSquaringServiceManager{ContractIncredibleSquaringServiceManagerCaller: ContractIncredibleSquaringServiceManagerCaller{contract: contract}, ContractIncredibleSquaringServiceManagerTransactor: ContractIncredibleSquaringServiceManagerTransactor{contract: contract}, ContractIncredibleSquaringServiceManagerFilterer: ContractIncredibleSquaringServiceManagerFilterer{contract: contract}}, nil +} + +// ContractIncredibleSquaringServiceManager is an auto generated Go binding around an Ethereum contract. +type ContractIncredibleSquaringServiceManager struct { + ContractIncredibleSquaringServiceManagerCaller // Read-only binding to the contract + ContractIncredibleSquaringServiceManagerTransactor // Write-only binding to the contract + ContractIncredibleSquaringServiceManagerFilterer // Log filterer for contract events +} + +// ContractIncredibleSquaringServiceManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type ContractIncredibleSquaringServiceManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractIncredibleSquaringServiceManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ContractIncredibleSquaringServiceManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractIncredibleSquaringServiceManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ContractIncredibleSquaringServiceManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractIncredibleSquaringServiceManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ContractIncredibleSquaringServiceManagerSession struct { + Contract *ContractIncredibleSquaringServiceManager // 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 +} + +// ContractIncredibleSquaringServiceManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ContractIncredibleSquaringServiceManagerCallerSession struct { + Contract *ContractIncredibleSquaringServiceManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ContractIncredibleSquaringServiceManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ContractIncredibleSquaringServiceManagerTransactorSession struct { + Contract *ContractIncredibleSquaringServiceManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ContractIncredibleSquaringServiceManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type ContractIncredibleSquaringServiceManagerRaw struct { + Contract *ContractIncredibleSquaringServiceManager // Generic contract binding to access the raw methods on +} + +// ContractIncredibleSquaringServiceManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ContractIncredibleSquaringServiceManagerCallerRaw struct { + Contract *ContractIncredibleSquaringServiceManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// ContractIncredibleSquaringServiceManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ContractIncredibleSquaringServiceManagerTransactorRaw struct { + Contract *ContractIncredibleSquaringServiceManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewContractIncredibleSquaringServiceManager creates a new instance of ContractIncredibleSquaringServiceManager, bound to a specific deployed contract. +func NewContractIncredibleSquaringServiceManager(address common.Address, backend bind.ContractBackend) (*ContractIncredibleSquaringServiceManager, error) { + contract, err := bindContractIncredibleSquaringServiceManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringServiceManager{ContractIncredibleSquaringServiceManagerCaller: ContractIncredibleSquaringServiceManagerCaller{contract: contract}, ContractIncredibleSquaringServiceManagerTransactor: ContractIncredibleSquaringServiceManagerTransactor{contract: contract}, ContractIncredibleSquaringServiceManagerFilterer: ContractIncredibleSquaringServiceManagerFilterer{contract: contract}}, nil +} + +// NewContractIncredibleSquaringServiceManagerCaller creates a new read-only instance of ContractIncredibleSquaringServiceManager, bound to a specific deployed contract. +func NewContractIncredibleSquaringServiceManagerCaller(address common.Address, caller bind.ContractCaller) (*ContractIncredibleSquaringServiceManagerCaller, error) { + contract, err := bindContractIncredibleSquaringServiceManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringServiceManagerCaller{contract: contract}, nil +} + +// NewContractIncredibleSquaringServiceManagerTransactor creates a new write-only instance of ContractIncredibleSquaringServiceManager, bound to a specific deployed contract. +func NewContractIncredibleSquaringServiceManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractIncredibleSquaringServiceManagerTransactor, error) { + contract, err := bindContractIncredibleSquaringServiceManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringServiceManagerTransactor{contract: contract}, nil +} + +// NewContractIncredibleSquaringServiceManagerFilterer creates a new log filterer instance of ContractIncredibleSquaringServiceManager, bound to a specific deployed contract. +func NewContractIncredibleSquaringServiceManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractIncredibleSquaringServiceManagerFilterer, error) { + contract, err := bindContractIncredibleSquaringServiceManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringServiceManagerFilterer{contract: contract}, nil +} + +// bindContractIncredibleSquaringServiceManager binds a generic wrapper to an already deployed contract. +func bindContractIncredibleSquaringServiceManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ContractIncredibleSquaringServiceManagerMetaData.GetAbi() + 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 (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ContractIncredibleSquaringServiceManager.Contract.ContractIncredibleSquaringServiceManagerCaller.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 (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.ContractIncredibleSquaringServiceManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.ContractIncredibleSquaringServiceManagerTransactor.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 (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ContractIncredibleSquaringServiceManager.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 (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.contract.Transact(opts, method, params...) +} + +// AvsDirectory is a free data retrieval call binding the contract method 0x6b3aa72e. +// +// Solidity: function avsDirectory() view returns(address) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerCaller) AvsDirectory(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringServiceManager.contract.Call(opts, &out, "avsDirectory") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// AvsDirectory is a free data retrieval call binding the contract method 0x6b3aa72e. +// +// Solidity: function avsDirectory() view returns(address) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerSession) AvsDirectory() (common.Address, error) { + return _ContractIncredibleSquaringServiceManager.Contract.AvsDirectory(&_ContractIncredibleSquaringServiceManager.CallOpts) +} + +// AvsDirectory is a free data retrieval call binding the contract method 0x6b3aa72e. +// +// Solidity: function avsDirectory() view returns(address) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerCallerSession) AvsDirectory() (common.Address, error) { + return _ContractIncredibleSquaringServiceManager.Contract.AvsDirectory(&_ContractIncredibleSquaringServiceManager.CallOpts) +} + +// GetOperatorRestakedStrategies is a free data retrieval call binding the contract method 0x33cfb7b7. +// +// Solidity: function getOperatorRestakedStrategies(address operator) view returns(address[]) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerCaller) GetOperatorRestakedStrategies(opts *bind.CallOpts, operator common.Address) ([]common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringServiceManager.contract.Call(opts, &out, "getOperatorRestakedStrategies", operator) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// GetOperatorRestakedStrategies is a free data retrieval call binding the contract method 0x33cfb7b7. +// +// Solidity: function getOperatorRestakedStrategies(address operator) view returns(address[]) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerSession) GetOperatorRestakedStrategies(operator common.Address) ([]common.Address, error) { + return _ContractIncredibleSquaringServiceManager.Contract.GetOperatorRestakedStrategies(&_ContractIncredibleSquaringServiceManager.CallOpts, operator) +} + +// GetOperatorRestakedStrategies is a free data retrieval call binding the contract method 0x33cfb7b7. +// +// Solidity: function getOperatorRestakedStrategies(address operator) view returns(address[]) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerCallerSession) GetOperatorRestakedStrategies(operator common.Address) ([]common.Address, error) { + return _ContractIncredibleSquaringServiceManager.Contract.GetOperatorRestakedStrategies(&_ContractIncredibleSquaringServiceManager.CallOpts, operator) +} + +// GetRestakeableStrategies is a free data retrieval call binding the contract method 0xe481af9d. +// +// Solidity: function getRestakeableStrategies() view returns(address[]) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerCaller) GetRestakeableStrategies(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringServiceManager.contract.Call(opts, &out, "getRestakeableStrategies") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// GetRestakeableStrategies is a free data retrieval call binding the contract method 0xe481af9d. +// +// Solidity: function getRestakeableStrategies() view returns(address[]) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerSession) GetRestakeableStrategies() ([]common.Address, error) { + return _ContractIncredibleSquaringServiceManager.Contract.GetRestakeableStrategies(&_ContractIncredibleSquaringServiceManager.CallOpts) +} + +// GetRestakeableStrategies is a free data retrieval call binding the contract method 0xe481af9d. +// +// Solidity: function getRestakeableStrategies() view returns(address[]) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerCallerSession) GetRestakeableStrategies() ([]common.Address, error) { + return _ContractIncredibleSquaringServiceManager.Contract.GetRestakeableStrategies(&_ContractIncredibleSquaringServiceManager.CallOpts) +} + +// IncredibleSquaringTaskManager is a free data retrieval call binding the contract method 0x77ef731d. +// +// Solidity: function incredibleSquaringTaskManager() view returns(address) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerCaller) IncredibleSquaringTaskManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringServiceManager.contract.Call(opts, &out, "incredibleSquaringTaskManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// IncredibleSquaringTaskManager is a free data retrieval call binding the contract method 0x77ef731d. +// +// Solidity: function incredibleSquaringTaskManager() view returns(address) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerSession) IncredibleSquaringTaskManager() (common.Address, error) { + return _ContractIncredibleSquaringServiceManager.Contract.IncredibleSquaringTaskManager(&_ContractIncredibleSquaringServiceManager.CallOpts) +} + +// IncredibleSquaringTaskManager is a free data retrieval call binding the contract method 0x77ef731d. +// +// Solidity: function incredibleSquaringTaskManager() view returns(address) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerCallerSession) IncredibleSquaringTaskManager() (common.Address, error) { + return _ContractIncredibleSquaringServiceManager.Contract.IncredibleSquaringTaskManager(&_ContractIncredibleSquaringServiceManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringServiceManager.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 (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerSession) Owner() (common.Address, error) { + return _ContractIncredibleSquaringServiceManager.Contract.Owner(&_ContractIncredibleSquaringServiceManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerCallerSession) Owner() (common.Address, error) { + return _ContractIncredibleSquaringServiceManager.Contract.Owner(&_ContractIncredibleSquaringServiceManager.CallOpts) +} + +// DeregisterOperatorFromAVS is a paid mutator transaction binding the contract method 0xa364f4da. +// +// Solidity: function deregisterOperatorFromAVS(address operator) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactor) DeregisterOperatorFromAVS(opts *bind.TransactOpts, operator common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.contract.Transact(opts, "deregisterOperatorFromAVS", operator) +} + +// DeregisterOperatorFromAVS is a paid mutator transaction binding the contract method 0xa364f4da. +// +// Solidity: function deregisterOperatorFromAVS(address operator) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerSession) DeregisterOperatorFromAVS(operator common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.DeregisterOperatorFromAVS(&_ContractIncredibleSquaringServiceManager.TransactOpts, operator) +} + +// DeregisterOperatorFromAVS is a paid mutator transaction binding the contract method 0xa364f4da. +// +// Solidity: function deregisterOperatorFromAVS(address operator) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactorSession) DeregisterOperatorFromAVS(operator common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.DeregisterOperatorFromAVS(&_ContractIncredibleSquaringServiceManager.TransactOpts, operator) +} + +// FreezeOperator is a paid mutator transaction binding the contract method 0x38c8ee64. +// +// Solidity: function freezeOperator(address operatorAddr) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactor) FreezeOperator(opts *bind.TransactOpts, operatorAddr common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.contract.Transact(opts, "freezeOperator", operatorAddr) +} + +// FreezeOperator is a paid mutator transaction binding the contract method 0x38c8ee64. +// +// Solidity: function freezeOperator(address operatorAddr) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerSession) FreezeOperator(operatorAddr common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.FreezeOperator(&_ContractIncredibleSquaringServiceManager.TransactOpts, operatorAddr) +} + +// FreezeOperator is a paid mutator transaction binding the contract method 0x38c8ee64. +// +// Solidity: function freezeOperator(address operatorAddr) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactorSession) FreezeOperator(operatorAddr common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.FreezeOperator(&_ContractIncredibleSquaringServiceManager.TransactOpts, operatorAddr) +} + +// PayForRange is a paid mutator transaction binding the contract method 0x1b445516. +// +// Solidity: function payForRange(((address,uint96)[],address,uint256,uint32,uint32)[] rangePayments) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactor) PayForRange(opts *bind.TransactOpts, rangePayments []IPaymentCoordinatorRangePayment) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.contract.Transact(opts, "payForRange", rangePayments) +} + +// PayForRange is a paid mutator transaction binding the contract method 0x1b445516. +// +// Solidity: function payForRange(((address,uint96)[],address,uint256,uint32,uint32)[] rangePayments) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerSession) PayForRange(rangePayments []IPaymentCoordinatorRangePayment) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.PayForRange(&_ContractIncredibleSquaringServiceManager.TransactOpts, rangePayments) +} + +// PayForRange is a paid mutator transaction binding the contract method 0x1b445516. +// +// Solidity: function payForRange(((address,uint96)[],address,uint256,uint32,uint32)[] rangePayments) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactorSession) PayForRange(rangePayments []IPaymentCoordinatorRangePayment) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.PayForRange(&_ContractIncredibleSquaringServiceManager.TransactOpts, rangePayments) +} + +// RegisterOperatorToAVS is a paid mutator transaction binding the contract method 0x9926ee7d. +// +// Solidity: function registerOperatorToAVS(address operator, (bytes,bytes32,uint256) operatorSignature) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactor) RegisterOperatorToAVS(opts *bind.TransactOpts, operator common.Address, operatorSignature ISignatureUtilsSignatureWithSaltAndExpiry) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.contract.Transact(opts, "registerOperatorToAVS", operator, operatorSignature) +} + +// RegisterOperatorToAVS is a paid mutator transaction binding the contract method 0x9926ee7d. +// +// Solidity: function registerOperatorToAVS(address operator, (bytes,bytes32,uint256) operatorSignature) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerSession) RegisterOperatorToAVS(operator common.Address, operatorSignature ISignatureUtilsSignatureWithSaltAndExpiry) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.RegisterOperatorToAVS(&_ContractIncredibleSquaringServiceManager.TransactOpts, operator, operatorSignature) +} + +// RegisterOperatorToAVS is a paid mutator transaction binding the contract method 0x9926ee7d. +// +// Solidity: function registerOperatorToAVS(address operator, (bytes,bytes32,uint256) operatorSignature) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactorSession) RegisterOperatorToAVS(operator common.Address, operatorSignature ISignatureUtilsSignatureWithSaltAndExpiry) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.RegisterOperatorToAVS(&_ContractIncredibleSquaringServiceManager.TransactOpts, operator, operatorSignature) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerSession) RenounceOwnership() (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.RenounceOwnership(&_ContractIncredibleSquaringServiceManager.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.RenounceOwnership(&_ContractIncredibleSquaringServiceManager.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.TransferOwnership(&_ContractIncredibleSquaringServiceManager.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.TransferOwnership(&_ContractIncredibleSquaringServiceManager.TransactOpts, newOwner) +} + +// UpdateAVSMetadataURI is a paid mutator transaction binding the contract method 0xa98fb355. +// +// Solidity: function updateAVSMetadataURI(string _metadataURI) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactor) UpdateAVSMetadataURI(opts *bind.TransactOpts, _metadataURI string) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.contract.Transact(opts, "updateAVSMetadataURI", _metadataURI) +} + +// UpdateAVSMetadataURI is a paid mutator transaction binding the contract method 0xa98fb355. +// +// Solidity: function updateAVSMetadataURI(string _metadataURI) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerSession) UpdateAVSMetadataURI(_metadataURI string) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.UpdateAVSMetadataURI(&_ContractIncredibleSquaringServiceManager.TransactOpts, _metadataURI) +} + +// UpdateAVSMetadataURI is a paid mutator transaction binding the contract method 0xa98fb355. +// +// Solidity: function updateAVSMetadataURI(string _metadataURI) returns() +func (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerTransactorSession) UpdateAVSMetadataURI(_metadataURI string) (*types.Transaction, error) { + return _ContractIncredibleSquaringServiceManager.Contract.UpdateAVSMetadataURI(&_ContractIncredibleSquaringServiceManager.TransactOpts, _metadataURI) +} + +// ContractIncredibleSquaringServiceManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ContractIncredibleSquaringServiceManager contract. +type ContractIncredibleSquaringServiceManagerInitializedIterator struct { + Event *ContractIncredibleSquaringServiceManagerInitialized // 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 *ContractIncredibleSquaringServiceManagerInitializedIterator) 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(ContractIncredibleSquaringServiceManagerInitialized) + 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(ContractIncredibleSquaringServiceManagerInitialized) + 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 *ContractIncredibleSquaringServiceManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringServiceManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringServiceManagerInitialized represents a Initialized event raised by the ContractIncredibleSquaringServiceManager contract. +type ContractIncredibleSquaringServiceManagerInitialized 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 (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*ContractIncredibleSquaringServiceManagerInitializedIterator, error) { + + logs, sub, err := _ContractIncredibleSquaringServiceManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringServiceManagerInitializedIterator{contract: _ContractIncredibleSquaringServiceManager.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 (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringServiceManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _ContractIncredibleSquaringServiceManager.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(ContractIncredibleSquaringServiceManagerInitialized) + if err := _ContractIncredibleSquaringServiceManager.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 (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerFilterer) ParseInitialized(log types.Log) (*ContractIncredibleSquaringServiceManagerInitialized, error) { + event := new(ContractIncredibleSquaringServiceManagerInitialized) + if err := _ContractIncredibleSquaringServiceManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractIncredibleSquaringServiceManagerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ContractIncredibleSquaringServiceManager contract. +type ContractIncredibleSquaringServiceManagerOwnershipTransferredIterator struct { + Event *ContractIncredibleSquaringServiceManagerOwnershipTransferred // 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 *ContractIncredibleSquaringServiceManagerOwnershipTransferredIterator) 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(ContractIncredibleSquaringServiceManagerOwnershipTransferred) + 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(ContractIncredibleSquaringServiceManagerOwnershipTransferred) + 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 *ContractIncredibleSquaringServiceManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringServiceManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringServiceManagerOwnershipTransferred represents a OwnershipTransferred event raised by the ContractIncredibleSquaringServiceManager contract. +type ContractIncredibleSquaringServiceManagerOwnershipTransferred 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 (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ContractIncredibleSquaringServiceManagerOwnershipTransferredIterator, 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 := _ContractIncredibleSquaringServiceManager.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringServiceManagerOwnershipTransferredIterator{contract: _ContractIncredibleSquaringServiceManager.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 (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringServiceManagerOwnershipTransferred, 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 := _ContractIncredibleSquaringServiceManager.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(ContractIncredibleSquaringServiceManagerOwnershipTransferred) + if err := _ContractIncredibleSquaringServiceManager.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 (_ContractIncredibleSquaringServiceManager *ContractIncredibleSquaringServiceManagerFilterer) ParseOwnershipTransferred(log types.Log) (*ContractIncredibleSquaringServiceManagerOwnershipTransferred, error) { + event := new(ContractIncredibleSquaringServiceManagerOwnershipTransferred) + if err := _ContractIncredibleSquaringServiceManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/temp-incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager/binding.go b/temp-incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager/binding.go new file mode 100644 index 0000000..6f6d68f --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager/binding.go @@ -0,0 +1,2866 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contractIncredibleSquaringTaskManager + +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 + _ = abi.ConvertType +) + +// BN254G1Point is an auto generated low-level Go binding around an user-defined struct. +type BN254G1Point struct { + X *big.Int + Y *big.Int +} + +// BN254G2Point is an auto generated low-level Go binding around an user-defined struct. +type BN254G2Point struct { + X [2]*big.Int + Y [2]*big.Int +} + +// IBLSSignatureCheckerNonSignerStakesAndSignature is an auto generated low-level Go binding around an user-defined struct. +type IBLSSignatureCheckerNonSignerStakesAndSignature struct { + NonSignerQuorumBitmapIndices []uint32 + NonSignerPubkeys []BN254G1Point + QuorumApks []BN254G1Point + ApkG2 BN254G2Point + Sigma BN254G1Point + QuorumApkIndices []uint32 + TotalStakeIndices []uint32 + NonSignerStakeIndices [][]uint32 +} + +// IBLSSignatureCheckerQuorumStakeTotals is an auto generated low-level Go binding around an user-defined struct. +type IBLSSignatureCheckerQuorumStakeTotals struct { + SignedStakeForQuorum []*big.Int + TotalStakeForQuorum []*big.Int +} + +// IIncredibleSquaringTaskManagerTask is an auto generated low-level Go binding around an user-defined struct. +type IIncredibleSquaringTaskManagerTask struct { + NumberToBeSquared *big.Int + TaskCreatedBlock uint32 + QuorumNumbers []byte + QuorumThresholdPercentage uint32 +} + +// IIncredibleSquaringTaskManagerTaskResponse is an auto generated low-level Go binding around an user-defined struct. +type IIncredibleSquaringTaskManagerTaskResponse struct { + ReferenceTaskIndex uint32 + NumberSquared *big.Int +} + +// IIncredibleSquaringTaskManagerTaskResponseMetadata is an auto generated low-level Go binding around an user-defined struct. +type IIncredibleSquaringTaskManagerTaskResponseMetadata struct { + TaskResponsedBlock uint32 + HashOfNonSigners [32]byte +} + +// OperatorStateRetrieverCheckSignaturesIndices is an auto generated low-level Go binding around an user-defined struct. +type OperatorStateRetrieverCheckSignaturesIndices struct { + NonSignerQuorumBitmapIndices []uint32 + QuorumApkIndices []uint32 + TotalStakeIndices []uint32 + NonSignerStakeIndices [][]uint32 +} + +// OperatorStateRetrieverOperator is an auto generated low-level Go binding around an user-defined struct. +type OperatorStateRetrieverOperator struct { + Operator common.Address + OperatorId [32]byte + Stake *big.Int +} + +// ContractIncredibleSquaringTaskManagerMetaData contains all meta data concerning the ContractIncredibleSquaringTaskManager contract. +var ContractIncredibleSquaringTaskManagerMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_registryCoordinator\",\"type\":\"address\",\"internalType\":\"contractIRegistryCoordinator\"},{\"name\":\"_taskResponseWindowBlock\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"TASK_CHALLENGE_WINDOW_BLOCK\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"TASK_RESPONSE_WINDOW_BLOCK\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"aggregator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"allTaskHashes\",\"inputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"allTaskResponses\",\"inputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"blsApkRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBLSApkRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"checkSignatures\",\"inputs\":[{\"name\":\"msgHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"quorumNumbers\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"referenceBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"params\",\"type\":\"tuple\",\"internalType\":\"structIBLSSignatureChecker.NonSignerStakesAndSignature\",\"components\":[{\"name\":\"nonSignerQuorumBitmapIndices\",\"type\":\"uint32[]\",\"internalType\":\"uint32[]\"},{\"name\":\"nonSignerPubkeys\",\"type\":\"tuple[]\",\"internalType\":\"structBN254.G1Point[]\",\"components\":[{\"name\":\"X\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"Y\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"quorumApks\",\"type\":\"tuple[]\",\"internalType\":\"structBN254.G1Point[]\",\"components\":[{\"name\":\"X\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"Y\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"apkG2\",\"type\":\"tuple\",\"internalType\":\"structBN254.G2Point\",\"components\":[{\"name\":\"X\",\"type\":\"uint256[2]\",\"internalType\":\"uint256[2]\"},{\"name\":\"Y\",\"type\":\"uint256[2]\",\"internalType\":\"uint256[2]\"}]},{\"name\":\"sigma\",\"type\":\"tuple\",\"internalType\":\"structBN254.G1Point\",\"components\":[{\"name\":\"X\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"Y\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"quorumApkIndices\",\"type\":\"uint32[]\",\"internalType\":\"uint32[]\"},{\"name\":\"totalStakeIndices\",\"type\":\"uint32[]\",\"internalType\":\"uint32[]\"},{\"name\":\"nonSignerStakeIndices\",\"type\":\"uint32[][]\",\"internalType\":\"uint32[][]\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIBLSSignatureChecker.QuorumStakeTotals\",\"components\":[{\"name\":\"signedStakeForQuorum\",\"type\":\"uint96[]\",\"internalType\":\"uint96[]\"},{\"name\":\"totalStakeForQuorum\",\"type\":\"uint96[]\",\"internalType\":\"uint96[]\"}]},{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"createNewTask\",\"inputs\":[{\"name\":\"numberToBeSquared\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"quorumThresholdPercentage\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"quorumNumbers\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegation\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIDelegationManager\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"generator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getCheckSignaturesIndices\",\"inputs\":[{\"name\":\"registryCoordinator\",\"type\":\"address\",\"internalType\":\"contractIRegistryCoordinator\"},{\"name\":\"referenceBlockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"quorumNumbers\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"nonSignerOperatorIds\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structOperatorStateRetriever.CheckSignaturesIndices\",\"components\":[{\"name\":\"nonSignerQuorumBitmapIndices\",\"type\":\"uint32[]\",\"internalType\":\"uint32[]\"},{\"name\":\"quorumApkIndices\",\"type\":\"uint32[]\",\"internalType\":\"uint32[]\"},{\"name\":\"totalStakeIndices\",\"type\":\"uint32[]\",\"internalType\":\"uint32[]\"},{\"name\":\"nonSignerStakeIndices\",\"type\":\"uint32[][]\",\"internalType\":\"uint32[][]\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getOperatorState\",\"inputs\":[{\"name\":\"registryCoordinator\",\"type\":\"address\",\"internalType\":\"contractIRegistryCoordinator\"},{\"name\":\"quorumNumbers\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"blockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple[][]\",\"internalType\":\"structOperatorStateRetriever.Operator[][]\",\"components\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stake\",\"type\":\"uint96\",\"internalType\":\"uint96\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getOperatorState\",\"inputs\":[{\"name\":\"registryCoordinator\",\"type\":\"address\",\"internalType\":\"contractIRegistryCoordinator\"},{\"name\":\"operatorId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"blockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"tuple[][]\",\"internalType\":\"structOperatorStateRetriever.Operator[][]\",\"components\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operatorId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"stake\",\"type\":\"uint96\",\"internalType\":\"uint96\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getQuorumBitmapsAtBlockNumber\",\"inputs\":[{\"name\":\"registryCoordinator\",\"type\":\"address\",\"internalType\":\"contractIRegistryCoordinator\"},{\"name\":\"operatorIds\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"},{\"name\":\"blockNumber\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256[]\",\"internalType\":\"uint256[]\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTaskResponseWindowBlock\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_pauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"initialOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_aggregator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_generator\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"latestTaskNum\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"pauseAll\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauserRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"raiseAndResolveChallenge\",\"inputs\":[{\"name\":\"task\",\"type\":\"tuple\",\"internalType\":\"structIIncredibleSquaringTaskManager.Task\",\"components\":[{\"name\":\"numberToBeSquared\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"taskCreatedBlock\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"quorumNumbers\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"quorumThresholdPercentage\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"taskResponse\",\"type\":\"tuple\",\"internalType\":\"structIIncredibleSquaringTaskManager.TaskResponse\",\"components\":[{\"name\":\"referenceTaskIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"numberSquared\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"taskResponseMetadata\",\"type\":\"tuple\",\"internalType\":\"structIIncredibleSquaringTaskManager.TaskResponseMetadata\",\"components\":[{\"name\":\"taskResponsedBlock\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"hashOfNonSigners\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"pubkeysOfNonSigningOperators\",\"type\":\"tuple[]\",\"internalType\":\"structBN254.G1Point[]\",\"components\":[{\"name\":\"X\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"Y\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"registryCoordinator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIRegistryCoordinator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"respondToTask\",\"inputs\":[{\"name\":\"task\",\"type\":\"tuple\",\"internalType\":\"structIIncredibleSquaringTaskManager.Task\",\"components\":[{\"name\":\"numberToBeSquared\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"taskCreatedBlock\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"quorumNumbers\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"quorumThresholdPercentage\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"taskResponse\",\"type\":\"tuple\",\"internalType\":\"structIIncredibleSquaringTaskManager.TaskResponse\",\"components\":[{\"name\":\"referenceTaskIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"numberSquared\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"nonSignerStakesAndSignature\",\"type\":\"tuple\",\"internalType\":\"structIBLSSignatureChecker.NonSignerStakesAndSignature\",\"components\":[{\"name\":\"nonSignerQuorumBitmapIndices\",\"type\":\"uint32[]\",\"internalType\":\"uint32[]\"},{\"name\":\"nonSignerPubkeys\",\"type\":\"tuple[]\",\"internalType\":\"structBN254.G1Point[]\",\"components\":[{\"name\":\"X\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"Y\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"quorumApks\",\"type\":\"tuple[]\",\"internalType\":\"structBN254.G1Point[]\",\"components\":[{\"name\":\"X\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"Y\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"apkG2\",\"type\":\"tuple\",\"internalType\":\"structBN254.G2Point\",\"components\":[{\"name\":\"X\",\"type\":\"uint256[2]\",\"internalType\":\"uint256[2]\"},{\"name\":\"Y\",\"type\":\"uint256[2]\",\"internalType\":\"uint256[2]\"}]},{\"name\":\"sigma\",\"type\":\"tuple\",\"internalType\":\"structBN254.G1Point\",\"components\":[{\"name\":\"X\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"Y\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"quorumApkIndices\",\"type\":\"uint32[]\",\"internalType\":\"uint32[]\"},{\"name\":\"totalStakeIndices\",\"type\":\"uint32[]\",\"internalType\":\"uint32[]\"},{\"name\":\"nonSignerStakeIndices\",\"type\":\"uint32[][]\",\"internalType\":\"uint32[][]\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPauserRegistry\",\"inputs\":[{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"internalType\":\"contractIPauserRegistry\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setStaleStakesForbidden\",\"inputs\":[{\"name\":\"value\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stakeRegistry\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIStakeRegistry\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"staleStakesForbidden\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"taskNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"taskSuccesfullyChallenged\",\"inputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"trySignatureAndApkVerification\",\"inputs\":[{\"name\":\"msgHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"apk\",\"type\":\"tuple\",\"internalType\":\"structBN254.G1Point\",\"components\":[{\"name\":\"X\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"Y\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"apkG2\",\"type\":\"tuple\",\"internalType\":\"structBN254.G2Point\",\"components\":[{\"name\":\"X\",\"type\":\"uint256[2]\",\"internalType\":\"uint256[2]\"},{\"name\":\"Y\",\"type\":\"uint256[2]\",\"internalType\":\"uint256[2]\"}]},{\"name\":\"sigma\",\"type\":\"tuple\",\"internalType\":\"structBN254.G1Point\",\"components\":[{\"name\":\"X\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"Y\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"outputs\":[{\"name\":\"pairingSuccessful\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"siganatureIsValid\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NewTaskCreated\",\"inputs\":[{\"name\":\"taskIndex\",\"type\":\"uint32\",\"indexed\":true,\"internalType\":\"uint32\"},{\"name\":\"task\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIIncredibleSquaringTaskManager.Task\",\"components\":[{\"name\":\"numberToBeSquared\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"taskCreatedBlock\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"quorumNumbers\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"quorumThresholdPercentage\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}],\"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\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PauserRegistrySet\",\"inputs\":[{\"name\":\"pauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"},{\"name\":\"newPauserRegistry\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"contractIPauserRegistry\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"StaleStakesForbiddenUpdate\",\"inputs\":[{\"name\":\"value\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TaskChallengedSuccessfully\",\"inputs\":[{\"name\":\"taskIndex\",\"type\":\"uint32\",\"indexed\":true,\"internalType\":\"uint32\"},{\"name\":\"challenger\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TaskChallengedUnsuccessfully\",\"inputs\":[{\"name\":\"taskIndex\",\"type\":\"uint32\",\"indexed\":true,\"internalType\":\"uint32\"},{\"name\":\"challenger\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TaskCompleted\",\"inputs\":[{\"name\":\"taskIndex\",\"type\":\"uint32\",\"indexed\":true,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TaskResponded\",\"inputs\":[{\"name\":\"taskResponse\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIIncredibleSquaringTaskManager.TaskResponse\",\"components\":[{\"name\":\"referenceTaskIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"numberSquared\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"taskResponseMetadata\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structIIncredibleSquaringTaskManager.TaskResponseMetadata\",\"components\":[{\"name\":\"taskResponsedBlock\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"hashOfNonSigners\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newPausedStatus\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162005e9638038062005e968339810160408190526200003591620001f7565b81806001600160a01b03166080816001600160a01b031681525050806001600160a01b031663683048356040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200008f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b591906200023e565b6001600160a01b031660a0816001600160a01b031681525050806001600160a01b0316635df459466040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200010d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200013391906200023e565b6001600160a01b031660c0816001600160a01b03168152505060a0516001600160a01b031663df5cf7236040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200018d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b391906200023e565b6001600160a01b031660e052506097805460ff1916600117905563ffffffff16610100525062000265565b6001600160a01b0381168114620001f457600080fd5b50565b600080604083850312156200020b57600080fd5b82516200021881620001de565b602084015190925063ffffffff811681146200023357600080fd5b809150509250929050565b6000602082840312156200025157600080fd5b81516200025e81620001de565b9392505050565b60805160a05160c05160e05161010051615b9f620002f76000396000818161027d0152818161059c015261195c0152600081816105650152612bee01526000818161041e0152818161224b0152612dd001526000818161044501528181612fa6015261316801526000818161049201528181610e0b015281816128d801528181612a510152612c8b0152615b9f6000f3fe608060405234801561001057600080fd5b506004361061021c5760003560e01c80636b532e9e116101255780638da5cb5b116100ad578063f2fde38b1161007c578063f2fde38b14610587578063f5c9899d1461059a578063f63c5bab146105c0578063f8c8765e146105c8578063fabc1cbc146105db57600080fd5b80638da5cb5b14610521578063b98d090814610532578063cefdc1d41461053f578063df5cf7231461056057600080fd5b8063715018a6116100f4578063715018a6146104d557806372d18e8d146104dd5780637afa1eed146104eb578063886f1195146104fe5780638b00ce7c1461051157600080fd5b80636b532e9e146104675780636b92787e1461047a5780636d14a9871461048d5780636efb4636146104b457600080fd5b80634f739f74116101a85780635c155662116101775780635c155662146103ce5780635c975abb146103ee5780635decc3f5146103f65780635df4594614610419578063683048351461044057600080fd5b80634f739f7414610360578063595c6a67146103805780635ac86ab7146103885780635baec9a0146103bb57600080fd5b8063245a7bfc116101ef578063245a7bfc146102b45780632cb223d5146102df5780632d89f6fc1461030d5780633563b0d11461032d578063416c7e5e1461034d57600080fd5b806310d67a2f14610221578063136439dd14610236578063171f1d5b146102495780631ad4318914610278575b600080fd5b61023461022f3660046146c1565b6105ee565b005b6102346102443660046146de565b6106aa565b61025c61025736600461485c565b6107e9565b6040805192151583529015156020830152015b60405180910390f35b61029f7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161026f565b60cd546102c7906001600160a01b031681565b6040516001600160a01b03909116815260200161026f565b6102ff6102ed3660046148ca565b60cb6020526000908152604090205481565b60405190815260200161026f565b6102ff61031b3660046148ca565b60ca6020526000908152604090205481565b61034061033b3660046148e7565b610973565b60405161026f9190614a42565b61023461035b366004614a6a565b610e09565b61037361036e366004614acf565b610f7e565b60405161026f9190614bd3565b6102346116a4565b6103ab610396366004614c9d565b606654600160ff9092169190911b9081161490565b604051901515815260200161026f565b6102346103c9366004614f88565b61176b565b6103e16103dc366004614ffc565b611bea565b60405161026f91906150a8565b6066546102ff565b6103ab6104043660046148ca565b60cc6020526000908152604090205460ff1681565b6102c77f000000000000000000000000000000000000000000000000000000000000000081565b6102c77f000000000000000000000000000000000000000000000000000000000000000081565b6102346104753660046150ec565b611db2565b610234610488366004615172565b612384565b6102c77f000000000000000000000000000000000000000000000000000000000000000081565b6104c76104c23660046151cd565b612525565b60405161026f92919061528d565b61023461341d565b60c95463ffffffff1661029f565b60ce546102c7906001600160a01b031681565b6065546102c7906001600160a01b031681565b60c95461029f9063ffffffff1681565b6033546001600160a01b03166102c7565b6097546103ab9060ff1681565b61055261054d3660046152d6565b613431565b60405161026f929190615318565b6102c77f000000000000000000000000000000000000000000000000000000000000000081565b6102346105953660046146c1565b6135c3565b7f000000000000000000000000000000000000000000000000000000000000000061029f565b61029f606481565b6102346105d6366004615339565b613639565b6102346105e93660046146de565b61378a565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610641573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106659190615395565b6001600160a01b0316336001600160a01b03161461069e5760405162461bcd60e51b8152600401610695906153b2565b60405180910390fd5b6106a7816138e6565b50565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156106f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071691906153fc565b6107325760405162461bcd60e51b815260040161069590615419565b606654818116146107ab5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610695565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b60008060007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018787600001518860200151886000015160006002811061083157610831615461565b60200201518951600160200201518a6020015160006002811061085657610856615461565b60200201518b6020015160016002811061087257610872615461565b602090810291909101518c518d8301516040516108cf9a99989796959401988952602089019790975260408801959095526060870193909352608086019190915260a085015260c084015260e08301526101008201526101200190565b6040516020818303038152906040528051906020012060001c6108f29190615477565b905061096561090b61090488846139dd565b8690613a74565b610913613b08565b61095b61094c85610946604080518082018252600080825260209182015281518083019092526001825260029082015290565b906139dd565b6109558c613bc8565b90613a74565b886201d4c0613c58565b909890975095505050505050565b60606000846001600160a01b031663683048356040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d99190615395565b90506000856001600160a01b0316639e9923c26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3f9190615395565b90506000866001600160a01b0316635df459466040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa59190615395565b9050600086516001600160401b03811115610ac257610ac26146f7565b604051908082528060200260200182016040528015610af557816020015b6060815260200190600190039081610ae05790505b50905060005b8751811015610dfd576000888281518110610b1857610b18615461565b0160200151604051638902624560e01b815260f89190911c6004820181905263ffffffff8a16602483015291506000906001600160a01b03871690638902624590604401600060405180830381865afa158015610b79573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ba19190810190615499565b905080516001600160401b03811115610bbc57610bbc6146f7565b604051908082528060200260200182016040528015610c0757816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181610bda5790505b50848481518110610c1a57610c1a615461565b602002602001018190525060005b8151811015610de7576040518060600160405280876001600160a01b03166347b314e8858581518110610c5d57610c5d615461565b60200260200101516040518263ffffffff1660e01b8152600401610c8391815260200190565b602060405180830381865afa158015610ca0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc49190615395565b6001600160a01b03168152602001838381518110610ce457610ce4615461565b60200260200101518152602001896001600160a01b031663fa28c627858581518110610d1257610d12615461565b60209081029190910101516040516001600160e01b031960e084901b168152600481019190915260ff8816602482015263ffffffff8f166044820152606401602060405180830381865afa158015610d6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d929190615529565b6001600160601b0316815250858581518110610db057610db0615461565b60200260200101518281518110610dc957610dc9615461565b60200260200101819052508080610ddf90615568565b915050610c28565b5050508080610df590615568565b915050610afb565b50979650505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8b9190615395565b6001600160a01b0316336001600160a01b031614610f375760405162461bcd60e51b815260206004820152605c60248201527f424c535369676e6174757265436865636b65722e6f6e6c79436f6f7264696e6160448201527f746f724f776e65723a2063616c6c6572206973206e6f7420746865206f776e6560648201527f72206f6620746865207265676973747279436f6f7264696e61746f7200000000608482015260a401610695565b6097805460ff19168215159081179091556040519081527f40e4ed880a29e0f6ddce307457fb75cddf4feef7d3ecb0301bfdf4976a0e2dfc9060200160405180910390a150565b610fa96040518060800160405280606081526020016060815260200160608152602001606081525090565b6000876001600160a01b031663683048356040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fe9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100d9190615395565b905061103a6040518060800160405280606081526020016060815260200160608152602001606081525090565b6040516361c8a12f60e11b81526001600160a01b038a169063c391425e9061106a908b9089908990600401615583565b600060405180830381865afa158015611087573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110af91908101906155cd565b81526040516340e03a8160e11b81526001600160a01b038316906381c07502906110e1908b908b908b90600401615684565b600060405180830381865afa1580156110fe573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261112691908101906155cd565b6040820152856001600160401b03811115611143576111436146f7565b60405190808252806020026020018201604052801561117657816020015b60608152602001906001900390816111615790505b50606082015260005b60ff81168711156115b5576000856001600160401b038111156111a4576111a46146f7565b6040519080825280602002602001820160405280156111cd578160200160208202803683370190505b5083606001518360ff16815181106111e7576111e7615461565b602002602001018190525060005b868110156114b55760008c6001600160a01b03166304ec63518a8a8581811061122057611220615461565b905060200201358e8860000151868151811061123e5761123e615461565b60200260200101516040518463ffffffff1660e01b815260040161127b9392919092835263ffffffff918216602084015216604082015260600190565b602060405180830381865afa158015611298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bc91906156ad565b90506001600160c01b0381166113605760405162461bcd60e51b815260206004820152605c60248201527f4f70657261746f7253746174655265747269657665722e676574436865636b5360448201527f69676e617475726573496e64696365733a206f70657261746f72206d7573742060648201527f6265207265676973746572656420617420626c6f636b6e756d62657200000000608482015260a401610695565b8a8a8560ff1681811061137557611375615461565b6001600160c01b03841692013560f81c9190911c6001908116141590506114a257856001600160a01b031663dd9846b98a8a858181106113b7576113b7615461565b905060200201358d8d8860ff168181106113d3576113d3615461565b6040516001600160e01b031960e087901b1681526004810194909452919091013560f81c60248301525063ffffffff8f166044820152606401602060405180830381865afa158015611429573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144d91906156d6565b85606001518560ff168151811061146657611466615461565b6020026020010151848151811061147f5761147f615461565b63ffffffff909216602092830291909101909101528261149e81615568565b9350505b50806114ad81615568565b9150506111f5565b506000816001600160401b038111156114d0576114d06146f7565b6040519080825280602002602001820160405280156114f9578160200160208202803683370190505b50905060005b8281101561157a5784606001518460ff168151811061152057611520615461565b6020026020010151818151811061153957611539615461565b602002602001015182828151811061155357611553615461565b63ffffffff909216602092830291909101909101528061157281615568565b9150506114ff565b508084606001518460ff168151811061159557611595615461565b6020026020010181905250505080806115ad906156f3565b91505061117f565b506000896001600160a01b0316635df459466040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a9190615395565b60405163354952a360e21b81529091506001600160a01b0382169063d5254a8c9061164d908b908b908e90600401615713565b600060405180830381865afa15801561166a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261169291908101906155cd565b60208301525098975050505050505050565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156116ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171091906153fc565b61172c5760405162461bcd60e51b815260040161069590615419565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b60cd546001600160a01b031633146117c55760405162461bcd60e51b815260206004820152601d60248201527f41676772656761746f72206d757374206265207468652063616c6c65720000006044820152606401610695565b60006117d760408501602086016148ca565b90503660006117e9604087018761573d565b9092509050600061180060808801606089016148ca565b905060ca600061181360208901896148ca565b63ffffffff1663ffffffff168152602001908152602001600020548760405160200161183f9190615783565b60405160208183030381529060405280519060200120146118c85760405162461bcd60e51b815260206004820152603d60248201527f737570706c696564207461736b20646f6573206e6f74206d617463682074686560448201527f206f6e65207265636f7264656420696e2074686520636f6e74726163740000006064820152608401610695565b600060cb816118da60208a018a6148ca565b63ffffffff1663ffffffff16815260200190815260200160002054146119575760405162461bcd60e51b815260206004820152602c60248201527f41676772656761746f722068617320616c726561647920726573706f6e64656460448201526b20746f20746865207461736b60a01b6064820152608401610695565b6119817f000000000000000000000000000000000000000000000000000000000000000085615824565b63ffffffff164363ffffffff1611156119f25760405162461bcd60e51b815260206004820152602d60248201527f41676772656761746f722068617320726573706f6e64656420746f207468652060448201526c7461736b20746f6f206c61746560981b6064820152608401610695565b600086604051602001611a05919061586a565b604051602081830303815290604052805190602001209050600080611a2d8387878a8c612525565b9150915060005b85811015611b2c578460ff1683602001518281518110611a5657611a56615461565b6020026020010151611a689190615878565b6001600160601b0316606484600001518381518110611a8957611a89615461565b60200260200101516001600160601b0316611aa491906158a7565b1015611b1a576040805162461bcd60e51b81526020600482015260248101919091527f5369676e61746f7269657320646f206e6f74206f776e206174206c656173742060448201527f7468726573686f6c642070657263656e74616765206f6620612071756f72756d6064820152608401610695565b80611b2481615568565b915050611a34565b5060408051808201825263ffffffff43168152602080820184905291519091611b59918c918491016158c6565b6040516020818303038152906040528051906020012060cb60008c6000016020810190611b8691906148ca565b63ffffffff1663ffffffff168152602001908152602001600020819055507f349c1ee60e4e8972ee9dba642c1774543d5c4136879b7f4caaf04bf81a487a2a8a82604051611bd59291906158c6565b60405180910390a15050505050505050505050565b60606000846001600160a01b031663c391425e84866040518363ffffffff1660e01b8152600401611c1c9291906158f2565b600060405180830381865afa158015611c39573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c6191908101906155cd565b9050600084516001600160401b03811115611c7e57611c7e6146f7565b604051908082528060200260200182016040528015611ca7578160200160208202803683370190505b50905060005b8551811015611da857866001600160a01b03166304ec6351878381518110611cd757611cd7615461565b602002602001015187868581518110611cf257611cf2615461565b60200260200101516040518463ffffffff1660e01b8152600401611d2f9392919092835263ffffffff918216602084015216604082015260600190565b602060405180830381865afa158015611d4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7091906156ad565b6001600160c01b0316828281518110611d8b57611d8b615461565b602090810291909101015280611da081615568565b915050611cad565b5095945050505050565b6000611dc160208501856148ca565b63ffffffff8116600090815260cb6020526040902054909150853590611e335760405162461bcd60e51b815260206004820152602160248201527f5461736b206861736e2774206265656e20726573706f6e64656420746f2079656044820152601d60fa1b6064820152608401610695565b8484604051602001611e46929190615946565b60408051601f19818403018152918152815160209283012063ffffffff8516600090815260cb90935291205414611ee55760405162461bcd60e51b815260206004820152603d60248201527f5461736b20726573706f6e736520646f6573206e6f74206d617463682074686560448201527f206f6e65207265636f7264656420696e2074686520636f6e74726163740000006064820152608401610695565b63ffffffff8216600090815260cc602052604090205460ff1615611f7d5760405162461bcd60e51b815260206004820152604360248201527f54686520726573706f6e736520746f2074686973207461736b2068617320616c60448201527f7265616479206265656e206368616c6c656e676564207375636365737366756c606482015262363c9760e91b608482015260a401610695565b6064611f8c60208601866148ca565b611f969190615824565b63ffffffff164363ffffffff1611156120175760405162461bcd60e51b815260206004820152603760248201527f546865206368616c6c656e676520706572696f6420666f72207468697320746160448201527f736b2068617320616c726561647920657870697265642e0000000000000000006064820152608401610695565b600061202382806158a7565b905060208601358114600181141561207157604051339063ffffffff8616907ffd3e26beeb5967fc5a57a0446914eabc45b4aa474c67a51b4b5160cac60ddb0590600090a35050505061237e565b600085516001600160401b0381111561208c5761208c6146f7565b6040519080825280602002602001820160405280156120b5578160200160208202803683370190505b50905060005b8651811015612127576120f88782815181106120d9576120d9615461565b6020026020010151805160009081526020918201519091526040902090565b82828151811061210a5761210a615461565b60209081029190910101528061211f81615568565b9150506120bb565b50600061213a60408b0160208c016148ca565b8260405160200161214c92919061597c565b604051602081830303815290604052805190602001209050876020013581146121f65760405162461bcd60e51b815260206004820152605060248201527f546865207075626b657973206f66206e6f6e2d7369676e696e67206f7065726160448201527f746f727320737570706c69656420627920746865206368616c6c656e6765722060648201526f30b932903737ba1031b7b93932b1ba1760811b608482015260a401610695565b600087516001600160401b03811115612211576122116146f7565b60405190808252806020026020018201604052801561223a578160200160208202803683370190505b50905060005b885181101561232d577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e8bb9ae685838151811061228a5761228a615461565b60200260200101516040518263ffffffff1660e01b81526004016122b091815260200190565b602060405180830381865afa1580156122cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122f19190615395565b82828151811061230357612303615461565b6001600160a01b03909216602092830291909101909101528061232581615568565b915050612240565b5063ffffffff8716600081815260cc6020526040808220805460ff19166001179055513392917fc20d1bb0f1623680306b83d4ff4bb99a2beb9d86d97832f3ca40fd13a29df1ec91a3505050505050505b50505050565b60ce546001600160a01b031633146123e85760405162461bcd60e51b815260206004820152602160248201527f5461736b2067656e657261746f72206d757374206265207468652063616c6c656044820152603960f91b6064820152608401610695565b61241f604051806080016040528060008152602001600063ffffffff16815260200160608152602001600063ffffffff1681525090565b84815263ffffffff438116602080840191909152908516606083015260408051601f8501839004830281018301909152838152908490849081908401838280828437600092019190915250505050604080830191909152516124859082906020016159c4565b60408051601f19818403018152828252805160209182012060c9805463ffffffff908116600090815260ca90945293909220555416907f1695b8d06ec800b4615e745cfb5bd00c1f2875615d42925c3b5afa543bb24c48906124e89084906159c4565b60405180910390a260c9546125049063ffffffff166001615824565b60c9805463ffffffff191663ffffffff929092169190911790555050505050565b604080518082019091526060808252602082015260008461259c5760405162461bcd60e51b81526020600482015260376024820152600080516020615b4a83398151915260448201527f7265733a20656d7074792071756f72756d20696e7075740000000000000000006064820152608401610695565b604083015151851480156125b4575060a08301515185145b80156125c4575060c08301515185145b80156125d4575060e08301515185145b61263e5760405162461bcd60e51b81526020600482015260416024820152600080516020615b4a83398151915260448201527f7265733a20696e7075742071756f72756d206c656e677468206d69736d6174636064820152600d60fb1b608482015260a401610695565b825151602084015151146126b65760405162461bcd60e51b815260206004820152604460248201819052600080516020615b4a833981519152908201527f7265733a20696e707574206e6f6e7369676e6572206c656e677468206d69736d6064820152630c2e8c6d60e31b608482015260a401610695565b4363ffffffff168463ffffffff16106127255760405162461bcd60e51b815260206004820152603c6024820152600080516020615b4a83398151915260448201527f7265733a20696e76616c6964207265666572656e636520626c6f636b000000006064820152608401610695565b6040805180820182526000808252602080830191909152825180840190935260608084529083015290866001600160401b03811115612766576127666146f7565b60405190808252806020026020018201604052801561278f578160200160208202803683370190505b506020820152866001600160401b038111156127ad576127ad6146f7565b6040519080825280602002602001820160405280156127d6578160200160208202803683370190505b50815260408051808201909152606080825260208201528560200151516001600160401b0381111561280a5761280a6146f7565b604051908082528060200260200182016040528015612833578160200160208202803683370190505b5081526020860151516001600160401b03811115612853576128536146f7565b60405190808252806020026020018201604052801561287c578160200160208202803683370190505b508160200181905250600061294e8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051639aa1653d60e01b815290516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169350639aa1653d925060048083019260209291908290030181865afa158015612925573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129499190615a4f565b613e7c565b905060005b876020015151811015612bca57612979886020015182815181106120d9576120d9615461565b8360200151828151811061298f5761298f615461565b60209081029190910101528015612a4f5760208301516129b0600183615a6c565b815181106129c0576129c0615461565b602002602001015160001c836020015182815181106129e1576129e1615461565b602002602001015160001c11612a4f576040805162461bcd60e51b8152602060048201526024810191909152600080516020615b4a83398151915260448201527f7265733a206e6f6e5369676e65725075626b657973206e6f7420736f727465646064820152608401610695565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166304ec635184602001518381518110612a9457612a94615461565b60200260200101518b8b600001518581518110612ab357612ab3615461565b60200260200101516040518463ffffffff1660e01b8152600401612af09392919092835263ffffffff918216602084015216604082015260600190565b602060405180830381865afa158015612b0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b3191906156ad565b6001600160c01b031683600001518281518110612b5057612b50615461565b602002602001018181525050612bb6610904612b8a8486600001518581518110612b7c57612b7c615461565b602002602001015116613f0f565b8a602001518481518110612ba057612ba0615461565b6020026020010151613f3a90919063ffffffff16565b945080612bc281615568565b915050612953565b5050612bd58361401e565b60975490935060ff16600081612bec576000612c6e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c448feb86040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c6e9190615a83565b905060005b8a8110156132ec578215612dce578963ffffffff16827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663249a0c428f8f86818110612cca57612cca615461565b60405160e085901b6001600160e01b031916815292013560f81c600483015250602401602060405180830381865afa158015612d0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d2e9190615a83565b612d389190615a9c565b11612dce5760405162461bcd60e51b81526020600482015260666024820152600080516020615b4a83398151915260448201527f7265733a205374616b6552656769737472792075706461746573206d7573742060648201527f62652077697468696e207769746864726177616c44656c6179426c6f636b732060848201526577696e646f7760d01b60a482015260c401610695565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166368bccaac8d8d84818110612e0f57612e0f615461565b9050013560f81c60f81b60f81c8c8c60a001518581518110612e3357612e33615461565b60209081029190910101516040516001600160e01b031960e086901b16815260ff909316600484015263ffffffff9182166024840152166044820152606401602060405180830381865afa158015612e8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eb39190615ab4565b6001600160401b031916612ed68a6040015183815181106120d9576120d9615461565b67ffffffffffffffff191614612f725760405162461bcd60e51b81526020600482015260616024820152600080516020615b4a83398151915260448201527f7265733a2071756f72756d41706b206861736820696e2073746f72616765206460648201527f6f6573206e6f74206d617463682070726f76696465642071756f72756d2061706084820152606b60f81b60a482015260c401610695565b612fa289604001518281518110612f8b57612f8b615461565b602002602001015187613a7490919063ffffffff16565b95507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c8294c568d8d84818110612fe557612fe5615461565b9050013560f81c60f81b60f81c8c8c60c00151858151811061300957613009615461565b60209081029190910101516040516001600160e01b031960e086901b16815260ff909316600484015263ffffffff9182166024840152166044820152606401602060405180830381865afa158015613065573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130899190615529565b8560200151828151811061309f5761309f615461565b6001600160601b039092166020928302919091018201528501518051829081106130cb576130cb615461565b6020026020010151856000015182815181106130e9576130e9615461565b60200260200101906001600160601b031690816001600160601b0316815250506000805b8a60200151518110156132d7576131618660000151828151811061313357613133615461565b60200260200101518f8f8681811061314d5761314d615461565b600192013560f81c9290921c811614919050565b156132c5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f2be94ae8f8f868181106131a7576131a7615461565b9050013560f81c60f81b60f81c8e896020015185815181106131cb576131cb615461565b60200260200101518f60e0015188815181106131e9576131e9615461565b6020026020010151878151811061320257613202615461565b60209081029190910101516040516001600160e01b031960e087901b16815260ff909416600485015263ffffffff92831660248501526044840191909152166064820152608401602060405180830381865afa158015613266573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061328a9190615529565b875180518590811061329e5761329e615461565b602002602001018181516132b29190615adf565b6001600160601b03169052506001909101905b806132cf81615568565b91505061310d565b505080806132e490615568565b915050612c73565b5050506000806133068c868a606001518b608001516107e9565b91509150816133775760405162461bcd60e51b81526020600482015260436024820152600080516020615b4a83398151915260448201527f7265733a2070616972696e6720707265636f6d70696c652063616c6c206661696064820152621b195960ea1b608482015260a401610695565b806133d85760405162461bcd60e51b81526020600482015260396024820152600080516020615b4a83398151915260448201527f7265733a207369676e617475726520697320696e76616c6964000000000000006064820152608401610695565b505060008782602001516040516020016133f392919061597c565b60408051808303601f190181529190528051602090910120929b929a509198505050505050505050565b6134256140b9565b61342f6000614113565b565b604080516001808252818301909252600091606091839160208083019080368337019050509050848160008151811061346c5761346c615461565b60209081029190910101526040516361c8a12f60e11b81526000906001600160a01b0388169063c391425e906134a890889086906004016158f2565b600060405180830381865afa1580156134c5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134ed91908101906155cd565b6000815181106134ff576134ff615461565b60209081029190910101516040516304ec635160e01b81526004810188905263ffffffff87811660248301529091166044820181905291506000906001600160a01b038916906304ec635190606401602060405180830381865afa15801561356b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358f91906156ad565b6001600160c01b0316905060006135a582614165565b9050816135b38a838a610973565b9550955050505050935093915050565b6135cb6140b9565b6001600160a01b0381166136305760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610695565b6106a781614113565b600054610100900460ff16158080156136595750600054600160ff909116105b806136735750303b158015613673575060005460ff166001145b6136d65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610695565b6000805460ff1916600117905580156136f9576000805461ff0019166101001790555b613704856000614231565b61370d84614113565b60cd80546001600160a01b038086166001600160a01b03199283161790925560ce8054928516929091169190911790558015613783576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138019190615395565b6001600160a01b0316336001600160a01b0316146138315760405162461bcd60e51b8152600401610695906153b2565b6066541981196066541916146138af5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610695565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c906020016107de565b6001600160a01b0381166139745760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610695565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b60408051808201909152600080825260208201526139f96145d2565b835181526020808501519082015260408082018490526000908360608460076107d05a03fa9050808015613a2c57613a2e565bfe5b5080613a6c5760405162461bcd60e51b815260206004820152600d60248201526c1958cb5b5d5b0b59985a5b1959609a1b6044820152606401610695565b505092915050565b6040805180820190915260008082526020820152613a906145f0565b835181526020808501518183015283516040808401919091529084015160608301526000908360808460066107d05a03fa9050808015613a2c575080613a6c5760405162461bcd60e51b815260206004820152600d60248201526c1958cb5859190b59985a5b1959609a1b6044820152606401610695565b613b1061460e565b50604080516080810182527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c28183019081527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6060830152815281518083019092527f275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec82527f1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d60208381019190915281019190915290565b604080518082019091526000808252602082015260008080613bf8600080516020615b2a83398151915286615477565b90505b613c048161431b565b9093509150600080516020615b2a833981519152828309831415613c3e576040805180820190915290815260208101919091529392505050565b600080516020615b2a833981519152600182089050613bfb565b604080518082018252868152602080820186905282518084019093528683528201849052600091829190613c8a614633565b60005b6002811015613e4f576000613ca38260066158a7565b9050848260028110613cb757613cb7615461565b60200201515183613cc9836000615a9c565b600c8110613cd957613cd9615461565b6020020152848260028110613cf057613cf0615461565b60200201516020015183826001613d079190615a9c565b600c8110613d1757613d17615461565b6020020152838260028110613d2e57613d2e615461565b6020020151515183613d41836002615a9c565b600c8110613d5157613d51615461565b6020020152838260028110613d6857613d68615461565b6020020151516001602002015183613d81836003615a9c565b600c8110613d9157613d91615461565b6020020152838260028110613da857613da8615461565b602002015160200151600060028110613dc357613dc3615461565b602002015183613dd4836004615a9c565b600c8110613de457613de4615461565b6020020152838260028110613dfb57613dfb615461565b602002015160200151600160028110613e1657613e16615461565b602002015183613e27836005615a9c565b600c8110613e3757613e37615461565b60200201525080613e4781615568565b915050613c8d565b50613e58614652565b60006020826101808560088cfa9151919c9115159b50909950505050505050505050565b600080613e888461439d565b9050808360ff166001901b11613f065760405162461bcd60e51b815260206004820152603f60248201527f4269746d61705574696c732e6f72646572656442797465734172726179546f4260448201527f69746d61703a206269746d61702065786365656473206d61782076616c7565006064820152608401610695565b90505b92915050565b6000805b8215613f0957613f24600184615a6c565b9092169180613f3281615b07565b915050613f13565b60408051808201909152600080825260208201526102008261ffff1610613f965760405162461bcd60e51b815260206004820152601060248201526f7363616c61722d746f6f2d6c6172676560801b6044820152606401610695565b8161ffff1660011415613faa575081613f09565b6040805180820190915260008082526020820181905284906001905b8161ffff168661ffff161061401357600161ffff871660ff83161c81161415613ff657613ff38484613a74565b93505b6140008384613a74565b92506201fffe600192831b169101613fc6565b509195945050505050565b6040805180820190915260008082526020820152815115801561404357506020820151155b15614061575050604080518082019091526000808252602082015290565b604051806040016040528083600001518152602001600080516020615b2a83398151915284602001516140949190615477565b6140ac90600080516020615b2a833981519152615a6c565b905292915050565b919050565b6033546001600160a01b0316331461342f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610695565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b606060008061417384613f0f565b61ffff166001600160401b0381111561418e5761418e6146f7565b6040519080825280601f01601f1916602001820160405280156141b8576020820181803683370190505b5090506000805b8251821080156141d0575061010081105b15614227576001811b935085841615614217578060f81b8383815181106141f9576141f9615461565b60200101906001600160f81b031916908160001a9053508160010191505b61422081615568565b90506141bf565b5090949350505050565b6065546001600160a01b031615801561425257506001600160a01b03821615155b6142d45760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610695565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2614317826138e6565b5050565b60008080600080516020615b2a8339815191526003600080516020615b2a83398151915286600080516020615b2a833981519152888909090890506000614391827f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52600080516020615b2a83398151915261452a565b91959194509092505050565b6000610100825111156144265760405162461bcd60e51b8152602060048201526044602482018190527f4269746d61705574696c732e6f72646572656442797465734172726179546f42908201527f69746d61703a206f7264657265644279746573417272617920697320746f6f206064820152636c6f6e6760e01b608482015260a401610695565b815161443457506000919050565b6000808360008151811061444a5761444a615461565b0160200151600160f89190911c81901b92505b84518110156145215784818151811061447857614478615461565b0160200151600160f89190911c1b915082821161450d5760405162461bcd60e51b815260206004820152604760248201527f4269746d61705574696c732e6f72646572656442797465734172726179546f4260448201527f69746d61703a206f72646572656442797465734172726179206973206e6f74206064820152661bdc99195c995960ca1b608482015260a401610695565b9181179161451a81615568565b905061445d565b50909392505050565b600080614535614652565b61453d614670565b602080825281810181905260408201819052606082018890526080820187905260a082018690528260c08360056107d05a03fa9250828015613a2c5750826145c75760405162461bcd60e51b815260206004820152601a60248201527f424e3235342e6578704d6f643a2063616c6c206661696c7572650000000000006044820152606401610695565b505195945050505050565b60405180606001604052806003906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806040016040528061462161468e565b815260200161462e61468e565b905290565b604051806101800160405280600c906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180604001604052806002906020820280368337509192915050565b6001600160a01b03811681146106a757600080fd5b6000602082840312156146d357600080fd5b8135613f06816146ac565b6000602082840312156146f057600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561472f5761472f6146f7565b60405290565b60405161010081016001600160401b038111828210171561472f5761472f6146f7565b604051601f8201601f191681016001600160401b0381118282101715614780576147806146f7565b604052919050565b60006040828403121561479a57600080fd5b6147a261470d565b9050813581526020820135602082015292915050565b600082601f8301126147c957600080fd5b604051604081018181106001600160401b03821117156147eb576147eb6146f7565b806040525080604084018581111561480257600080fd5b845b81811015614013578035835260209283019201614804565b60006080828403121561482e57600080fd5b61483661470d565b905061484283836147b8565b815261485183604084016147b8565b602082015292915050565b600080600080610120858703121561487357600080fd5b843593506148848660208701614788565b9250614893866060870161481c565b91506148a28660e08701614788565b905092959194509250565b63ffffffff811681146106a757600080fd5b80356140b4816148ad565b6000602082840312156148dc57600080fd5b8135613f06816148ad565b6000806000606084860312156148fc57600080fd5b8335614907816146ac565b92506020848101356001600160401b038082111561492457600080fd5b818701915087601f83011261493857600080fd5b81358181111561494a5761494a6146f7565b61495c601f8201601f19168501614758565b9150808252888482850101111561497257600080fd5b8084840185840137600084828401015250809450505050614995604085016148bf565b90509250925092565b600081518084526020808501808196508360051b810191508286016000805b86811015614a34578385038a52825180518087529087019087870190845b81811015614a1f57835180516001600160a01b031684528a8101518b8501526040908101516001600160601b031690840152928901926060909201916001016149db565b50509a87019a955050918501916001016149bd565b509298975050505050505050565b602081526000614a55602083018461499e565b9392505050565b80151581146106a757600080fd5b600060208284031215614a7c57600080fd5b8135613f0681614a5c565b60008083601f840112614a9957600080fd5b5081356001600160401b03811115614ab057600080fd5b602083019150836020828501011115614ac857600080fd5b9250929050565b60008060008060008060808789031215614ae857600080fd5b8635614af3816146ac565b95506020870135614b03816148ad565b945060408701356001600160401b0380821115614b1f57600080fd5b614b2b8a838b01614a87565b90965094506060890135915080821115614b4457600080fd5b818901915089601f830112614b5857600080fd5b813581811115614b6757600080fd5b8a60208260051b8501011115614b7c57600080fd5b6020830194508093505050509295509295509295565b600081518084526020808501945080840160005b83811015614bc857815163ffffffff1687529582019590820190600101614ba6565b509495945050505050565b600060208083528351608082850152614bef60a0850182614b92565b905081850151601f1980868403016040870152614c0c8383614b92565b92506040870151915080868403016060870152614c298383614b92565b60608801518782038301608089015280518083529194508501925084840190600581901b8501860160005b82811015614c805784878303018452614c6e828751614b92565b95880195938801939150600101614c54565b509998505050505050505050565b60ff811681146106a757600080fd5b600060208284031215614caf57600080fd5b8135613f0681614c8e565b600060808284031215614ccc57600080fd5b50919050565b600060408284031215614ccc57600080fd5b60006001600160401b03821115614cfd57614cfd6146f7565b5060051b60200190565b600082601f830112614d1857600080fd5b81356020614d2d614d2883614ce4565b614758565b82815260059290921b84018101918181019086841115614d4c57600080fd5b8286015b84811015614d70578035614d63816148ad565b8352918301918301614d50565b509695505050505050565b600082601f830112614d8c57600080fd5b81356020614d9c614d2883614ce4565b82815260069290921b84018101918181019086841115614dbb57600080fd5b8286015b84811015614d7057614dd18882614788565b835291830191604001614dbf565b600082601f830112614df057600080fd5b81356020614e00614d2883614ce4565b82815260059290921b84018101918181019086841115614e1f57600080fd5b8286015b84811015614d705780356001600160401b03811115614e425760008081fd5b614e508986838b0101614d07565b845250918301918301614e23565b60006101808284031215614e7157600080fd5b614e79614735565b905081356001600160401b0380821115614e9257600080fd5b614e9e85838601614d07565b83526020840135915080821115614eb457600080fd5b614ec085838601614d7b565b60208401526040840135915080821115614ed957600080fd5b614ee585838601614d7b565b6040840152614ef7856060860161481c565b6060840152614f098560e08601614788565b6080840152610120840135915080821115614f2357600080fd5b614f2f85838601614d07565b60a0840152610140840135915080821115614f4957600080fd5b614f5585838601614d07565b60c0840152610160840135915080821115614f6f57600080fd5b50614f7c84828501614ddf565b60e08301525092915050565b600080600060808486031215614f9d57600080fd5b83356001600160401b0380821115614fb457600080fd5b614fc087838801614cba565b9450614fcf8760208801614cd2565b93506060860135915080821115614fe557600080fd5b50614ff286828701614e5e565b9150509250925092565b60008060006060848603121561501157600080fd5b833561501c816146ac565b92506020848101356001600160401b0381111561503857600080fd5b8501601f8101871361504957600080fd5b8035615057614d2882614ce4565b81815260059190911b8201830190838101908983111561507657600080fd5b928401925b828410156150945783358252928401929084019061507b565b8096505050505050614995604085016148bf565b6020808252825182820181905260009190848201906040850190845b818110156150e0578351835292840192918401916001016150c4565b50909695505050505050565b60008060008060c0858703121561510257600080fd5b84356001600160401b038082111561511957600080fd5b61512588838901614cba565b95506151348860208901614cd2565b94506151438860608901614cd2565b935060a087013591508082111561515957600080fd5b5061516687828801614d7b565b91505092959194509250565b6000806000806060858703121561518857600080fd5b84359350602085013561519a816148ad565b925060408501356001600160401b038111156151b557600080fd5b6151c187828801614a87565b95989497509550505050565b6000806000806000608086880312156151e557600080fd5b8535945060208601356001600160401b038082111561520357600080fd5b61520f89838a01614a87565b909650945060408801359150615224826148ad565b9092506060870135908082111561523a57600080fd5b5061524788828901614e5e565b9150509295509295909350565b600081518084526020808501945080840160005b83811015614bc85781516001600160601b031687529582019590820190600101615268565b60408152600083516040808401526152a86080840182615254565b90506020850151603f198483030160608501526152c58282615254565b925050508260208301529392505050565b6000806000606084860312156152eb57600080fd5b83356152f6816146ac565b925060208401359150604084013561530d816148ad565b809150509250925092565b828152604060208201526000615331604083018461499e565b949350505050565b6000806000806080858703121561534f57600080fd5b843561535a816146ac565b9350602085013561536a816146ac565b9250604085013561537a816146ac565b9150606085013561538a816146ac565b939692955090935050565b6000602082840312156153a757600080fd5b8151613f06816146ac565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b60006020828403121561540e57600080fd5b8151613f0681614a5c565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60008261549457634e487b7160e01b600052601260045260246000fd5b500690565b600060208083850312156154ac57600080fd5b82516001600160401b038111156154c257600080fd5b8301601f810185136154d357600080fd5b80516154e1614d2882614ce4565b81815260059190911b8201830190838101908783111561550057600080fd5b928401925b8284101561551e57835182529284019290840190615505565b979650505050505050565b60006020828403121561553b57600080fd5b81516001600160601b0381168114613f0657600080fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141561557c5761557c615552565b5060010190565b63ffffffff84168152604060208201819052810182905260006001600160fb1b038311156155b057600080fd5b8260051b8085606085013760009201606001918252509392505050565b600060208083850312156155e057600080fd5b82516001600160401b038111156155f657600080fd5b8301601f8101851361560757600080fd5b8051615615614d2882614ce4565b81815260059190911b8201830190838101908783111561563457600080fd5b928401925b8284101561551e57835161564c816148ad565b82529284019290840190615639565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b63ffffffff841681526040602082015260006156a460408301848661565b565b95945050505050565b6000602082840312156156bf57600080fd5b81516001600160c01b0381168114613f0657600080fd5b6000602082840312156156e857600080fd5b8151613f06816148ad565b600060ff821660ff81141561570a5761570a615552565b60010192915050565b60408152600061572760408301858761565b565b905063ffffffff83166020830152949350505050565b6000808335601e1984360301811261575457600080fd5b8301803591506001600160401b0382111561576e57600080fd5b602001915036819003821315614ac857600080fd5b60208152813560208201526000602083013561579e816148ad565b63ffffffff81166040840152506040830135601e198436030181126157c257600080fd5b830180356001600160401b038111156157da57600080fd5b8036038513156157e957600080fd5b6080606085015261580160a08501826020850161565b565b915050615810606085016148bf565b63ffffffff81166080850152509392505050565b600063ffffffff80831681851680830382111561584357615843615552565b01949350505050565b8035615857816148ad565b63ffffffff168252602090810135910152565b60408101613f09828461584c565b60006001600160601b038083168185168183048111821515161561589e5761589e615552565b02949350505050565b60008160001904831182151516156158c1576158c1615552565b500290565b608081016158d4828561584c565b63ffffffff8351166040830152602083015160608301529392505050565b60006040820163ffffffff851683526020604081850152818551808452606086019150828701935060005b818110156159395784518352938301939183019160010161591d565b5090979650505050505050565b60808101615954828561584c565b823561595f816148ad565b63ffffffff16604083015260209290920135606090910152919050565b63ffffffff60e01b8360e01b1681526000600482018351602080860160005b838110156159b75781518552938201939082019060010161599b565b5092979650505050505050565b6000602080835283518184015263ffffffff8185015116604084015260408401516080606085015280518060a086015260005b81811015615a135782810184015186820160c0015283016159f7565b81811115615a2557600060c083880101525b50606086015163ffffffff811660808701529250601f01601f19169390930160c001949350505050565b600060208284031215615a6157600080fd5b8151613f0681614c8e565b600082821015615a7e57615a7e615552565b500390565b600060208284031215615a9557600080fd5b5051919050565b60008219821115615aaf57615aaf615552565b500190565b600060208284031215615ac657600080fd5b815167ffffffffffffffff1981168114613f0657600080fd5b60006001600160601b0383811690831681811015615aff57615aff615552565b039392505050565b600061ffff80831681811415615b1f57615b1f615552565b600101939250505056fe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47424c535369676e6174757265436865636b65722e636865636b5369676e617475a2646970667358221220f43d3574c3acebcece2bc7051e60a5c5dc7c8feae0125c754c62da48277a982664736f6c634300080c0033", +} + +// ContractIncredibleSquaringTaskManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use ContractIncredibleSquaringTaskManagerMetaData.ABI instead. +var ContractIncredibleSquaringTaskManagerABI = ContractIncredibleSquaringTaskManagerMetaData.ABI + +// ContractIncredibleSquaringTaskManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ContractIncredibleSquaringTaskManagerMetaData.Bin instead. +var ContractIncredibleSquaringTaskManagerBin = ContractIncredibleSquaringTaskManagerMetaData.Bin + +// DeployContractIncredibleSquaringTaskManager deploys a new Ethereum contract, binding an instance of ContractIncredibleSquaringTaskManager to it. +func DeployContractIncredibleSquaringTaskManager(auth *bind.TransactOpts, backend bind.ContractBackend, _registryCoordinator common.Address, _taskResponseWindowBlock uint32) (common.Address, *types.Transaction, *ContractIncredibleSquaringTaskManager, error) { + parsed, err := ContractIncredibleSquaringTaskManagerMetaData.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(ContractIncredibleSquaringTaskManagerBin), backend, _registryCoordinator, _taskResponseWindowBlock) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ContractIncredibleSquaringTaskManager{ContractIncredibleSquaringTaskManagerCaller: ContractIncredibleSquaringTaskManagerCaller{contract: contract}, ContractIncredibleSquaringTaskManagerTransactor: ContractIncredibleSquaringTaskManagerTransactor{contract: contract}, ContractIncredibleSquaringTaskManagerFilterer: ContractIncredibleSquaringTaskManagerFilterer{contract: contract}}, nil +} + +// ContractIncredibleSquaringTaskManager is an auto generated Go binding around an Ethereum contract. +type ContractIncredibleSquaringTaskManager struct { + ContractIncredibleSquaringTaskManagerCaller // Read-only binding to the contract + ContractIncredibleSquaringTaskManagerTransactor // Write-only binding to the contract + ContractIncredibleSquaringTaskManagerFilterer // Log filterer for contract events +} + +// ContractIncredibleSquaringTaskManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type ContractIncredibleSquaringTaskManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractIncredibleSquaringTaskManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ContractIncredibleSquaringTaskManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractIncredibleSquaringTaskManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ContractIncredibleSquaringTaskManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractIncredibleSquaringTaskManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ContractIncredibleSquaringTaskManagerSession struct { + Contract *ContractIncredibleSquaringTaskManager // 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 +} + +// ContractIncredibleSquaringTaskManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ContractIncredibleSquaringTaskManagerCallerSession struct { + Contract *ContractIncredibleSquaringTaskManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ContractIncredibleSquaringTaskManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ContractIncredibleSquaringTaskManagerTransactorSession struct { + Contract *ContractIncredibleSquaringTaskManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ContractIncredibleSquaringTaskManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type ContractIncredibleSquaringTaskManagerRaw struct { + Contract *ContractIncredibleSquaringTaskManager // Generic contract binding to access the raw methods on +} + +// ContractIncredibleSquaringTaskManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ContractIncredibleSquaringTaskManagerCallerRaw struct { + Contract *ContractIncredibleSquaringTaskManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// ContractIncredibleSquaringTaskManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ContractIncredibleSquaringTaskManagerTransactorRaw struct { + Contract *ContractIncredibleSquaringTaskManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewContractIncredibleSquaringTaskManager creates a new instance of ContractIncredibleSquaringTaskManager, bound to a specific deployed contract. +func NewContractIncredibleSquaringTaskManager(address common.Address, backend bind.ContractBackend) (*ContractIncredibleSquaringTaskManager, error) { + contract, err := bindContractIncredibleSquaringTaskManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManager{ContractIncredibleSquaringTaskManagerCaller: ContractIncredibleSquaringTaskManagerCaller{contract: contract}, ContractIncredibleSquaringTaskManagerTransactor: ContractIncredibleSquaringTaskManagerTransactor{contract: contract}, ContractIncredibleSquaringTaskManagerFilterer: ContractIncredibleSquaringTaskManagerFilterer{contract: contract}}, nil +} + +// NewContractIncredibleSquaringTaskManagerCaller creates a new read-only instance of ContractIncredibleSquaringTaskManager, bound to a specific deployed contract. +func NewContractIncredibleSquaringTaskManagerCaller(address common.Address, caller bind.ContractCaller) (*ContractIncredibleSquaringTaskManagerCaller, error) { + contract, err := bindContractIncredibleSquaringTaskManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerCaller{contract: contract}, nil +} + +// NewContractIncredibleSquaringTaskManagerTransactor creates a new write-only instance of ContractIncredibleSquaringTaskManager, bound to a specific deployed contract. +func NewContractIncredibleSquaringTaskManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractIncredibleSquaringTaskManagerTransactor, error) { + contract, err := bindContractIncredibleSquaringTaskManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerTransactor{contract: contract}, nil +} + +// NewContractIncredibleSquaringTaskManagerFilterer creates a new log filterer instance of ContractIncredibleSquaringTaskManager, bound to a specific deployed contract. +func NewContractIncredibleSquaringTaskManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractIncredibleSquaringTaskManagerFilterer, error) { + contract, err := bindContractIncredibleSquaringTaskManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerFilterer{contract: contract}, nil +} + +// bindContractIncredibleSquaringTaskManager binds a generic wrapper to an already deployed contract. +func bindContractIncredibleSquaringTaskManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ContractIncredibleSquaringTaskManagerMetaData.GetAbi() + 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 (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ContractIncredibleSquaringTaskManager.Contract.ContractIncredibleSquaringTaskManagerCaller.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 (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.ContractIncredibleSquaringTaskManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.ContractIncredibleSquaringTaskManagerTransactor.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 (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ContractIncredibleSquaringTaskManager.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 (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.contract.Transact(opts, method, params...) +} + +// TASKCHALLENGEWINDOWBLOCK is a free data retrieval call binding the contract method 0xf63c5bab. +// +// Solidity: function TASK_CHALLENGE_WINDOW_BLOCK() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) TASKCHALLENGEWINDOWBLOCK(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "TASK_CHALLENGE_WINDOW_BLOCK") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// TASKCHALLENGEWINDOWBLOCK is a free data retrieval call binding the contract method 0xf63c5bab. +// +// Solidity: function TASK_CHALLENGE_WINDOW_BLOCK() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) TASKCHALLENGEWINDOWBLOCK() (uint32, error) { + return _ContractIncredibleSquaringTaskManager.Contract.TASKCHALLENGEWINDOWBLOCK(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// TASKCHALLENGEWINDOWBLOCK is a free data retrieval call binding the contract method 0xf63c5bab. +// +// Solidity: function TASK_CHALLENGE_WINDOW_BLOCK() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) TASKCHALLENGEWINDOWBLOCK() (uint32, error) { + return _ContractIncredibleSquaringTaskManager.Contract.TASKCHALLENGEWINDOWBLOCK(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// TASKRESPONSEWINDOWBLOCK is a free data retrieval call binding the contract method 0x1ad43189. +// +// Solidity: function TASK_RESPONSE_WINDOW_BLOCK() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) TASKRESPONSEWINDOWBLOCK(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "TASK_RESPONSE_WINDOW_BLOCK") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// TASKRESPONSEWINDOWBLOCK is a free data retrieval call binding the contract method 0x1ad43189. +// +// Solidity: function TASK_RESPONSE_WINDOW_BLOCK() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) TASKRESPONSEWINDOWBLOCK() (uint32, error) { + return _ContractIncredibleSquaringTaskManager.Contract.TASKRESPONSEWINDOWBLOCK(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// TASKRESPONSEWINDOWBLOCK is a free data retrieval call binding the contract method 0x1ad43189. +// +// Solidity: function TASK_RESPONSE_WINDOW_BLOCK() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) TASKRESPONSEWINDOWBLOCK() (uint32, error) { + return _ContractIncredibleSquaringTaskManager.Contract.TASKRESPONSEWINDOWBLOCK(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// Aggregator is a free data retrieval call binding the contract method 0x245a7bfc. +// +// Solidity: function aggregator() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) Aggregator(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "aggregator") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Aggregator is a free data retrieval call binding the contract method 0x245a7bfc. +// +// Solidity: function aggregator() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) Aggregator() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Aggregator(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// Aggregator is a free data retrieval call binding the contract method 0x245a7bfc. +// +// Solidity: function aggregator() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) Aggregator() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Aggregator(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// AllTaskHashes is a free data retrieval call binding the contract method 0x2d89f6fc. +// +// Solidity: function allTaskHashes(uint32 ) view returns(bytes32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) AllTaskHashes(opts *bind.CallOpts, arg0 uint32) ([32]byte, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "allTaskHashes", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// AllTaskHashes is a free data retrieval call binding the contract method 0x2d89f6fc. +// +// Solidity: function allTaskHashes(uint32 ) view returns(bytes32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) AllTaskHashes(arg0 uint32) ([32]byte, error) { + return _ContractIncredibleSquaringTaskManager.Contract.AllTaskHashes(&_ContractIncredibleSquaringTaskManager.CallOpts, arg0) +} + +// AllTaskHashes is a free data retrieval call binding the contract method 0x2d89f6fc. +// +// Solidity: function allTaskHashes(uint32 ) view returns(bytes32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) AllTaskHashes(arg0 uint32) ([32]byte, error) { + return _ContractIncredibleSquaringTaskManager.Contract.AllTaskHashes(&_ContractIncredibleSquaringTaskManager.CallOpts, arg0) +} + +// AllTaskResponses is a free data retrieval call binding the contract method 0x2cb223d5. +// +// Solidity: function allTaskResponses(uint32 ) view returns(bytes32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) AllTaskResponses(opts *bind.CallOpts, arg0 uint32) ([32]byte, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "allTaskResponses", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// AllTaskResponses is a free data retrieval call binding the contract method 0x2cb223d5. +// +// Solidity: function allTaskResponses(uint32 ) view returns(bytes32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) AllTaskResponses(arg0 uint32) ([32]byte, error) { + return _ContractIncredibleSquaringTaskManager.Contract.AllTaskResponses(&_ContractIncredibleSquaringTaskManager.CallOpts, arg0) +} + +// AllTaskResponses is a free data retrieval call binding the contract method 0x2cb223d5. +// +// Solidity: function allTaskResponses(uint32 ) view returns(bytes32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) AllTaskResponses(arg0 uint32) ([32]byte, error) { + return _ContractIncredibleSquaringTaskManager.Contract.AllTaskResponses(&_ContractIncredibleSquaringTaskManager.CallOpts, arg0) +} + +// BlsApkRegistry is a free data retrieval call binding the contract method 0x5df45946. +// +// Solidity: function blsApkRegistry() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) BlsApkRegistry(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "blsApkRegistry") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// BlsApkRegistry is a free data retrieval call binding the contract method 0x5df45946. +// +// Solidity: function blsApkRegistry() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) BlsApkRegistry() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.BlsApkRegistry(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// BlsApkRegistry is a free data retrieval call binding the contract method 0x5df45946. +// +// Solidity: function blsApkRegistry() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) BlsApkRegistry() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.BlsApkRegistry(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// CheckSignatures is a free data retrieval call binding the contract method 0x6efb4636. +// +// Solidity: function checkSignatures(bytes32 msgHash, bytes quorumNumbers, uint32 referenceBlockNumber, (uint32[],(uint256,uint256)[],(uint256,uint256)[],(uint256[2],uint256[2]),(uint256,uint256),uint32[],uint32[],uint32[][]) params) view returns((uint96[],uint96[]), bytes32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) CheckSignatures(opts *bind.CallOpts, msgHash [32]byte, quorumNumbers []byte, referenceBlockNumber uint32, params IBLSSignatureCheckerNonSignerStakesAndSignature) (IBLSSignatureCheckerQuorumStakeTotals, [32]byte, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "checkSignatures", msgHash, quorumNumbers, referenceBlockNumber, params) + + if err != nil { + return *new(IBLSSignatureCheckerQuorumStakeTotals), *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new(IBLSSignatureCheckerQuorumStakeTotals)).(*IBLSSignatureCheckerQuorumStakeTotals) + out1 := *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + + return out0, out1, err + +} + +// CheckSignatures is a free data retrieval call binding the contract method 0x6efb4636. +// +// Solidity: function checkSignatures(bytes32 msgHash, bytes quorumNumbers, uint32 referenceBlockNumber, (uint32[],(uint256,uint256)[],(uint256,uint256)[],(uint256[2],uint256[2]),(uint256,uint256),uint32[],uint32[],uint32[][]) params) view returns((uint96[],uint96[]), bytes32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) CheckSignatures(msgHash [32]byte, quorumNumbers []byte, referenceBlockNumber uint32, params IBLSSignatureCheckerNonSignerStakesAndSignature) (IBLSSignatureCheckerQuorumStakeTotals, [32]byte, error) { + return _ContractIncredibleSquaringTaskManager.Contract.CheckSignatures(&_ContractIncredibleSquaringTaskManager.CallOpts, msgHash, quorumNumbers, referenceBlockNumber, params) +} + +// CheckSignatures is a free data retrieval call binding the contract method 0x6efb4636. +// +// Solidity: function checkSignatures(bytes32 msgHash, bytes quorumNumbers, uint32 referenceBlockNumber, (uint32[],(uint256,uint256)[],(uint256,uint256)[],(uint256[2],uint256[2]),(uint256,uint256),uint32[],uint32[],uint32[][]) params) view returns((uint96[],uint96[]), bytes32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) CheckSignatures(msgHash [32]byte, quorumNumbers []byte, referenceBlockNumber uint32, params IBLSSignatureCheckerNonSignerStakesAndSignature) (IBLSSignatureCheckerQuorumStakeTotals, [32]byte, error) { + return _ContractIncredibleSquaringTaskManager.Contract.CheckSignatures(&_ContractIncredibleSquaringTaskManager.CallOpts, msgHash, quorumNumbers, referenceBlockNumber, params) +} + +// Delegation is a free data retrieval call binding the contract method 0xdf5cf723. +// +// Solidity: function delegation() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) Delegation(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "delegation") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Delegation is a free data retrieval call binding the contract method 0xdf5cf723. +// +// Solidity: function delegation() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) Delegation() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Delegation(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// Delegation is a free data retrieval call binding the contract method 0xdf5cf723. +// +// Solidity: function delegation() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) Delegation() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Delegation(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// Generator is a free data retrieval call binding the contract method 0x7afa1eed. +// +// Solidity: function generator() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) Generator(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "generator") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Generator is a free data retrieval call binding the contract method 0x7afa1eed. +// +// Solidity: function generator() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) Generator() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Generator(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// Generator is a free data retrieval call binding the contract method 0x7afa1eed. +// +// Solidity: function generator() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) Generator() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Generator(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// GetCheckSignaturesIndices is a free data retrieval call binding the contract method 0x4f739f74. +// +// Solidity: function getCheckSignaturesIndices(address registryCoordinator, uint32 referenceBlockNumber, bytes quorumNumbers, bytes32[] nonSignerOperatorIds) view returns((uint32[],uint32[],uint32[],uint32[][])) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) GetCheckSignaturesIndices(opts *bind.CallOpts, registryCoordinator common.Address, referenceBlockNumber uint32, quorumNumbers []byte, nonSignerOperatorIds [][32]byte) (OperatorStateRetrieverCheckSignaturesIndices, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "getCheckSignaturesIndices", registryCoordinator, referenceBlockNumber, quorumNumbers, nonSignerOperatorIds) + + if err != nil { + return *new(OperatorStateRetrieverCheckSignaturesIndices), err + } + + out0 := *abi.ConvertType(out[0], new(OperatorStateRetrieverCheckSignaturesIndices)).(*OperatorStateRetrieverCheckSignaturesIndices) + + return out0, err + +} + +// GetCheckSignaturesIndices is a free data retrieval call binding the contract method 0x4f739f74. +// +// Solidity: function getCheckSignaturesIndices(address registryCoordinator, uint32 referenceBlockNumber, bytes quorumNumbers, bytes32[] nonSignerOperatorIds) view returns((uint32[],uint32[],uint32[],uint32[][])) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) GetCheckSignaturesIndices(registryCoordinator common.Address, referenceBlockNumber uint32, quorumNumbers []byte, nonSignerOperatorIds [][32]byte) (OperatorStateRetrieverCheckSignaturesIndices, error) { + return _ContractIncredibleSquaringTaskManager.Contract.GetCheckSignaturesIndices(&_ContractIncredibleSquaringTaskManager.CallOpts, registryCoordinator, referenceBlockNumber, quorumNumbers, nonSignerOperatorIds) +} + +// GetCheckSignaturesIndices is a free data retrieval call binding the contract method 0x4f739f74. +// +// Solidity: function getCheckSignaturesIndices(address registryCoordinator, uint32 referenceBlockNumber, bytes quorumNumbers, bytes32[] nonSignerOperatorIds) view returns((uint32[],uint32[],uint32[],uint32[][])) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) GetCheckSignaturesIndices(registryCoordinator common.Address, referenceBlockNumber uint32, quorumNumbers []byte, nonSignerOperatorIds [][32]byte) (OperatorStateRetrieverCheckSignaturesIndices, error) { + return _ContractIncredibleSquaringTaskManager.Contract.GetCheckSignaturesIndices(&_ContractIncredibleSquaringTaskManager.CallOpts, registryCoordinator, referenceBlockNumber, quorumNumbers, nonSignerOperatorIds) +} + +// GetOperatorState is a free data retrieval call binding the contract method 0x3563b0d1. +// +// Solidity: function getOperatorState(address registryCoordinator, bytes quorumNumbers, uint32 blockNumber) view returns((address,bytes32,uint96)[][]) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) GetOperatorState(opts *bind.CallOpts, registryCoordinator common.Address, quorumNumbers []byte, blockNumber uint32) ([][]OperatorStateRetrieverOperator, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "getOperatorState", registryCoordinator, quorumNumbers, blockNumber) + + if err != nil { + return *new([][]OperatorStateRetrieverOperator), err + } + + out0 := *abi.ConvertType(out[0], new([][]OperatorStateRetrieverOperator)).(*[][]OperatorStateRetrieverOperator) + + return out0, err + +} + +// GetOperatorState is a free data retrieval call binding the contract method 0x3563b0d1. +// +// Solidity: function getOperatorState(address registryCoordinator, bytes quorumNumbers, uint32 blockNumber) view returns((address,bytes32,uint96)[][]) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) GetOperatorState(registryCoordinator common.Address, quorumNumbers []byte, blockNumber uint32) ([][]OperatorStateRetrieverOperator, error) { + return _ContractIncredibleSquaringTaskManager.Contract.GetOperatorState(&_ContractIncredibleSquaringTaskManager.CallOpts, registryCoordinator, quorumNumbers, blockNumber) +} + +// GetOperatorState is a free data retrieval call binding the contract method 0x3563b0d1. +// +// Solidity: function getOperatorState(address registryCoordinator, bytes quorumNumbers, uint32 blockNumber) view returns((address,bytes32,uint96)[][]) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) GetOperatorState(registryCoordinator common.Address, quorumNumbers []byte, blockNumber uint32) ([][]OperatorStateRetrieverOperator, error) { + return _ContractIncredibleSquaringTaskManager.Contract.GetOperatorState(&_ContractIncredibleSquaringTaskManager.CallOpts, registryCoordinator, quorumNumbers, blockNumber) +} + +// GetOperatorState0 is a free data retrieval call binding the contract method 0xcefdc1d4. +// +// Solidity: function getOperatorState(address registryCoordinator, bytes32 operatorId, uint32 blockNumber) view returns(uint256, (address,bytes32,uint96)[][]) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) GetOperatorState0(opts *bind.CallOpts, registryCoordinator common.Address, operatorId [32]byte, blockNumber uint32) (*big.Int, [][]OperatorStateRetrieverOperator, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "getOperatorState0", registryCoordinator, operatorId, blockNumber) + + if err != nil { + return *new(*big.Int), *new([][]OperatorStateRetrieverOperator), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out1 := *abi.ConvertType(out[1], new([][]OperatorStateRetrieverOperator)).(*[][]OperatorStateRetrieverOperator) + + return out0, out1, err + +} + +// GetOperatorState0 is a free data retrieval call binding the contract method 0xcefdc1d4. +// +// Solidity: function getOperatorState(address registryCoordinator, bytes32 operatorId, uint32 blockNumber) view returns(uint256, (address,bytes32,uint96)[][]) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) GetOperatorState0(registryCoordinator common.Address, operatorId [32]byte, blockNumber uint32) (*big.Int, [][]OperatorStateRetrieverOperator, error) { + return _ContractIncredibleSquaringTaskManager.Contract.GetOperatorState0(&_ContractIncredibleSquaringTaskManager.CallOpts, registryCoordinator, operatorId, blockNumber) +} + +// GetOperatorState0 is a free data retrieval call binding the contract method 0xcefdc1d4. +// +// Solidity: function getOperatorState(address registryCoordinator, bytes32 operatorId, uint32 blockNumber) view returns(uint256, (address,bytes32,uint96)[][]) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) GetOperatorState0(registryCoordinator common.Address, operatorId [32]byte, blockNumber uint32) (*big.Int, [][]OperatorStateRetrieverOperator, error) { + return _ContractIncredibleSquaringTaskManager.Contract.GetOperatorState0(&_ContractIncredibleSquaringTaskManager.CallOpts, registryCoordinator, operatorId, blockNumber) +} + +// GetQuorumBitmapsAtBlockNumber is a free data retrieval call binding the contract method 0x5c155662. +// +// Solidity: function getQuorumBitmapsAtBlockNumber(address registryCoordinator, bytes32[] operatorIds, uint32 blockNumber) view returns(uint256[]) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) GetQuorumBitmapsAtBlockNumber(opts *bind.CallOpts, registryCoordinator common.Address, operatorIds [][32]byte, blockNumber uint32) ([]*big.Int, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "getQuorumBitmapsAtBlockNumber", registryCoordinator, operatorIds, blockNumber) + + if err != nil { + return *new([]*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + + return out0, err + +} + +// GetQuorumBitmapsAtBlockNumber is a free data retrieval call binding the contract method 0x5c155662. +// +// Solidity: function getQuorumBitmapsAtBlockNumber(address registryCoordinator, bytes32[] operatorIds, uint32 blockNumber) view returns(uint256[]) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) GetQuorumBitmapsAtBlockNumber(registryCoordinator common.Address, operatorIds [][32]byte, blockNumber uint32) ([]*big.Int, error) { + return _ContractIncredibleSquaringTaskManager.Contract.GetQuorumBitmapsAtBlockNumber(&_ContractIncredibleSquaringTaskManager.CallOpts, registryCoordinator, operatorIds, blockNumber) +} + +// GetQuorumBitmapsAtBlockNumber is a free data retrieval call binding the contract method 0x5c155662. +// +// Solidity: function getQuorumBitmapsAtBlockNumber(address registryCoordinator, bytes32[] operatorIds, uint32 blockNumber) view returns(uint256[]) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) GetQuorumBitmapsAtBlockNumber(registryCoordinator common.Address, operatorIds [][32]byte, blockNumber uint32) ([]*big.Int, error) { + return _ContractIncredibleSquaringTaskManager.Contract.GetQuorumBitmapsAtBlockNumber(&_ContractIncredibleSquaringTaskManager.CallOpts, registryCoordinator, operatorIds, blockNumber) +} + +// GetTaskResponseWindowBlock is a free data retrieval call binding the contract method 0xf5c9899d. +// +// Solidity: function getTaskResponseWindowBlock() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) GetTaskResponseWindowBlock(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "getTaskResponseWindowBlock") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// GetTaskResponseWindowBlock is a free data retrieval call binding the contract method 0xf5c9899d. +// +// Solidity: function getTaskResponseWindowBlock() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) GetTaskResponseWindowBlock() (uint32, error) { + return _ContractIncredibleSquaringTaskManager.Contract.GetTaskResponseWindowBlock(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// GetTaskResponseWindowBlock is a free data retrieval call binding the contract method 0xf5c9899d. +// +// Solidity: function getTaskResponseWindowBlock() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) GetTaskResponseWindowBlock() (uint32, error) { + return _ContractIncredibleSquaringTaskManager.Contract.GetTaskResponseWindowBlock(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// LatestTaskNum is a free data retrieval call binding the contract method 0x8b00ce7c. +// +// Solidity: function latestTaskNum() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) LatestTaskNum(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "latestTaskNum") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// LatestTaskNum is a free data retrieval call binding the contract method 0x8b00ce7c. +// +// Solidity: function latestTaskNum() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) LatestTaskNum() (uint32, error) { + return _ContractIncredibleSquaringTaskManager.Contract.LatestTaskNum(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// LatestTaskNum is a free data retrieval call binding the contract method 0x8b00ce7c. +// +// Solidity: function latestTaskNum() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) LatestTaskNum() (uint32, error) { + return _ContractIncredibleSquaringTaskManager.Contract.LatestTaskNum(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.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 (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) Owner() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Owner(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) Owner() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Owner(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5ac86ab7. +// +// Solidity: function paused(uint8 index) view returns(bool) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) Paused(opts *bind.CallOpts, index uint8) (bool, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "paused", index) + + 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 0x5ac86ab7. +// +// Solidity: function paused(uint8 index) view returns(bool) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) Paused(index uint8) (bool, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Paused(&_ContractIncredibleSquaringTaskManager.CallOpts, index) +} + +// Paused is a free data retrieval call binding the contract method 0x5ac86ab7. +// +// Solidity: function paused(uint8 index) view returns(bool) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) Paused(index uint8) (bool, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Paused(&_ContractIncredibleSquaringTaskManager.CallOpts, index) +} + +// Paused0 is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(uint256) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) Paused0(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "paused0") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Paused0 is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(uint256) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) Paused0() (*big.Int, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Paused0(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// Paused0 is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(uint256) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) Paused0() (*big.Int, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Paused0(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// PauserRegistry is a free data retrieval call binding the contract method 0x886f1195. +// +// Solidity: function pauserRegistry() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) PauserRegistry(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "pauserRegistry") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PauserRegistry is a free data retrieval call binding the contract method 0x886f1195. +// +// Solidity: function pauserRegistry() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) PauserRegistry() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.PauserRegistry(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// PauserRegistry is a free data retrieval call binding the contract method 0x886f1195. +// +// Solidity: function pauserRegistry() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) PauserRegistry() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.PauserRegistry(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// RegistryCoordinator is a free data retrieval call binding the contract method 0x6d14a987. +// +// Solidity: function registryCoordinator() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) RegistryCoordinator(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "registryCoordinator") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// RegistryCoordinator is a free data retrieval call binding the contract method 0x6d14a987. +// +// Solidity: function registryCoordinator() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) RegistryCoordinator() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.RegistryCoordinator(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// RegistryCoordinator is a free data retrieval call binding the contract method 0x6d14a987. +// +// Solidity: function registryCoordinator() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) RegistryCoordinator() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.RegistryCoordinator(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// StakeRegistry is a free data retrieval call binding the contract method 0x68304835. +// +// Solidity: function stakeRegistry() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) StakeRegistry(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "stakeRegistry") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// StakeRegistry is a free data retrieval call binding the contract method 0x68304835. +// +// Solidity: function stakeRegistry() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) StakeRegistry() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.StakeRegistry(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// StakeRegistry is a free data retrieval call binding the contract method 0x68304835. +// +// Solidity: function stakeRegistry() view returns(address) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) StakeRegistry() (common.Address, error) { + return _ContractIncredibleSquaringTaskManager.Contract.StakeRegistry(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// StaleStakesForbidden is a free data retrieval call binding the contract method 0xb98d0908. +// +// Solidity: function staleStakesForbidden() view returns(bool) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) StaleStakesForbidden(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "staleStakesForbidden") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// StaleStakesForbidden is a free data retrieval call binding the contract method 0xb98d0908. +// +// Solidity: function staleStakesForbidden() view returns(bool) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) StaleStakesForbidden() (bool, error) { + return _ContractIncredibleSquaringTaskManager.Contract.StaleStakesForbidden(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// StaleStakesForbidden is a free data retrieval call binding the contract method 0xb98d0908. +// +// Solidity: function staleStakesForbidden() view returns(bool) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) StaleStakesForbidden() (bool, error) { + return _ContractIncredibleSquaringTaskManager.Contract.StaleStakesForbidden(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// TaskNumber is a free data retrieval call binding the contract method 0x72d18e8d. +// +// Solidity: function taskNumber() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) TaskNumber(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "taskNumber") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// TaskNumber is a free data retrieval call binding the contract method 0x72d18e8d. +// +// Solidity: function taskNumber() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) TaskNumber() (uint32, error) { + return _ContractIncredibleSquaringTaskManager.Contract.TaskNumber(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// TaskNumber is a free data retrieval call binding the contract method 0x72d18e8d. +// +// Solidity: function taskNumber() view returns(uint32) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) TaskNumber() (uint32, error) { + return _ContractIncredibleSquaringTaskManager.Contract.TaskNumber(&_ContractIncredibleSquaringTaskManager.CallOpts) +} + +// TaskSuccesfullyChallenged is a free data retrieval call binding the contract method 0x5decc3f5. +// +// Solidity: function taskSuccesfullyChallenged(uint32 ) view returns(bool) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) TaskSuccesfullyChallenged(opts *bind.CallOpts, arg0 uint32) (bool, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "taskSuccesfullyChallenged", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// TaskSuccesfullyChallenged is a free data retrieval call binding the contract method 0x5decc3f5. +// +// Solidity: function taskSuccesfullyChallenged(uint32 ) view returns(bool) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) TaskSuccesfullyChallenged(arg0 uint32) (bool, error) { + return _ContractIncredibleSquaringTaskManager.Contract.TaskSuccesfullyChallenged(&_ContractIncredibleSquaringTaskManager.CallOpts, arg0) +} + +// TaskSuccesfullyChallenged is a free data retrieval call binding the contract method 0x5decc3f5. +// +// Solidity: function taskSuccesfullyChallenged(uint32 ) view returns(bool) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) TaskSuccesfullyChallenged(arg0 uint32) (bool, error) { + return _ContractIncredibleSquaringTaskManager.Contract.TaskSuccesfullyChallenged(&_ContractIncredibleSquaringTaskManager.CallOpts, arg0) +} + +// TrySignatureAndApkVerification is a free data retrieval call binding the contract method 0x171f1d5b. +// +// Solidity: function trySignatureAndApkVerification(bytes32 msgHash, (uint256,uint256) apk, (uint256[2],uint256[2]) apkG2, (uint256,uint256) sigma) view returns(bool pairingSuccessful, bool siganatureIsValid) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCaller) TrySignatureAndApkVerification(opts *bind.CallOpts, msgHash [32]byte, apk BN254G1Point, apkG2 BN254G2Point, sigma BN254G1Point) (struct { + PairingSuccessful bool + SiganatureIsValid bool +}, error) { + var out []interface{} + err := _ContractIncredibleSquaringTaskManager.contract.Call(opts, &out, "trySignatureAndApkVerification", msgHash, apk, apkG2, sigma) + + outstruct := new(struct { + PairingSuccessful bool + SiganatureIsValid bool + }) + if err != nil { + return *outstruct, err + } + + outstruct.PairingSuccessful = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.SiganatureIsValid = *abi.ConvertType(out[1], new(bool)).(*bool) + + return *outstruct, err + +} + +// TrySignatureAndApkVerification is a free data retrieval call binding the contract method 0x171f1d5b. +// +// Solidity: function trySignatureAndApkVerification(bytes32 msgHash, (uint256,uint256) apk, (uint256[2],uint256[2]) apkG2, (uint256,uint256) sigma) view returns(bool pairingSuccessful, bool siganatureIsValid) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) TrySignatureAndApkVerification(msgHash [32]byte, apk BN254G1Point, apkG2 BN254G2Point, sigma BN254G1Point) (struct { + PairingSuccessful bool + SiganatureIsValid bool +}, error) { + return _ContractIncredibleSquaringTaskManager.Contract.TrySignatureAndApkVerification(&_ContractIncredibleSquaringTaskManager.CallOpts, msgHash, apk, apkG2, sigma) +} + +// TrySignatureAndApkVerification is a free data retrieval call binding the contract method 0x171f1d5b. +// +// Solidity: function trySignatureAndApkVerification(bytes32 msgHash, (uint256,uint256) apk, (uint256[2],uint256[2]) apkG2, (uint256,uint256) sigma) view returns(bool pairingSuccessful, bool siganatureIsValid) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerCallerSession) TrySignatureAndApkVerification(msgHash [32]byte, apk BN254G1Point, apkG2 BN254G2Point, sigma BN254G1Point) (struct { + PairingSuccessful bool + SiganatureIsValid bool +}, error) { + return _ContractIncredibleSquaringTaskManager.Contract.TrySignatureAndApkVerification(&_ContractIncredibleSquaringTaskManager.CallOpts, msgHash, apk, apkG2, sigma) +} + +// CreateNewTask is a paid mutator transaction binding the contract method 0x6b92787e. +// +// Solidity: function createNewTask(uint256 numberToBeSquared, uint32 quorumThresholdPercentage, bytes quorumNumbers) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactor) CreateNewTask(opts *bind.TransactOpts, numberToBeSquared *big.Int, quorumThresholdPercentage uint32, quorumNumbers []byte) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.contract.Transact(opts, "createNewTask", numberToBeSquared, quorumThresholdPercentage, quorumNumbers) +} + +// CreateNewTask is a paid mutator transaction binding the contract method 0x6b92787e. +// +// Solidity: function createNewTask(uint256 numberToBeSquared, uint32 quorumThresholdPercentage, bytes quorumNumbers) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) CreateNewTask(numberToBeSquared *big.Int, quorumThresholdPercentage uint32, quorumNumbers []byte) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.CreateNewTask(&_ContractIncredibleSquaringTaskManager.TransactOpts, numberToBeSquared, quorumThresholdPercentage, quorumNumbers) +} + +// CreateNewTask is a paid mutator transaction binding the contract method 0x6b92787e. +// +// Solidity: function createNewTask(uint256 numberToBeSquared, uint32 quorumThresholdPercentage, bytes quorumNumbers) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorSession) CreateNewTask(numberToBeSquared *big.Int, quorumThresholdPercentage uint32, quorumNumbers []byte) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.CreateNewTask(&_ContractIncredibleSquaringTaskManager.TransactOpts, numberToBeSquared, quorumThresholdPercentage, quorumNumbers) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf8c8765e. +// +// Solidity: function initialize(address _pauserRegistry, address initialOwner, address _aggregator, address _generator) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactor) Initialize(opts *bind.TransactOpts, _pauserRegistry common.Address, initialOwner common.Address, _aggregator common.Address, _generator common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.contract.Transact(opts, "initialize", _pauserRegistry, initialOwner, _aggregator, _generator) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf8c8765e. +// +// Solidity: function initialize(address _pauserRegistry, address initialOwner, address _aggregator, address _generator) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) Initialize(_pauserRegistry common.Address, initialOwner common.Address, _aggregator common.Address, _generator common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Initialize(&_ContractIncredibleSquaringTaskManager.TransactOpts, _pauserRegistry, initialOwner, _aggregator, _generator) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf8c8765e. +// +// Solidity: function initialize(address _pauserRegistry, address initialOwner, address _aggregator, address _generator) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorSession) Initialize(_pauserRegistry common.Address, initialOwner common.Address, _aggregator common.Address, _generator common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Initialize(&_ContractIncredibleSquaringTaskManager.TransactOpts, _pauserRegistry, initialOwner, _aggregator, _generator) +} + +// Pause is a paid mutator transaction binding the contract method 0x136439dd. +// +// Solidity: function pause(uint256 newPausedStatus) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactor) Pause(opts *bind.TransactOpts, newPausedStatus *big.Int) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.contract.Transact(opts, "pause", newPausedStatus) +} + +// Pause is a paid mutator transaction binding the contract method 0x136439dd. +// +// Solidity: function pause(uint256 newPausedStatus) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) Pause(newPausedStatus *big.Int) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Pause(&_ContractIncredibleSquaringTaskManager.TransactOpts, newPausedStatus) +} + +// Pause is a paid mutator transaction binding the contract method 0x136439dd. +// +// Solidity: function pause(uint256 newPausedStatus) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorSession) Pause(newPausedStatus *big.Int) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Pause(&_ContractIncredibleSquaringTaskManager.TransactOpts, newPausedStatus) +} + +// PauseAll is a paid mutator transaction binding the contract method 0x595c6a67. +// +// Solidity: function pauseAll() returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactor) PauseAll(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.contract.Transact(opts, "pauseAll") +} + +// PauseAll is a paid mutator transaction binding the contract method 0x595c6a67. +// +// Solidity: function pauseAll() returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) PauseAll() (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.PauseAll(&_ContractIncredibleSquaringTaskManager.TransactOpts) +} + +// PauseAll is a paid mutator transaction binding the contract method 0x595c6a67. +// +// Solidity: function pauseAll() returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorSession) PauseAll() (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.PauseAll(&_ContractIncredibleSquaringTaskManager.TransactOpts) +} + +// RaiseAndResolveChallenge is a paid mutator transaction binding the contract method 0x6b532e9e. +// +// Solidity: function raiseAndResolveChallenge((uint256,uint32,bytes,uint32) task, (uint32,uint256) taskResponse, (uint32,bytes32) taskResponseMetadata, (uint256,uint256)[] pubkeysOfNonSigningOperators) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactor) RaiseAndResolveChallenge(opts *bind.TransactOpts, task IIncredibleSquaringTaskManagerTask, taskResponse IIncredibleSquaringTaskManagerTaskResponse, taskResponseMetadata IIncredibleSquaringTaskManagerTaskResponseMetadata, pubkeysOfNonSigningOperators []BN254G1Point) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.contract.Transact(opts, "raiseAndResolveChallenge", task, taskResponse, taskResponseMetadata, pubkeysOfNonSigningOperators) +} + +// RaiseAndResolveChallenge is a paid mutator transaction binding the contract method 0x6b532e9e. +// +// Solidity: function raiseAndResolveChallenge((uint256,uint32,bytes,uint32) task, (uint32,uint256) taskResponse, (uint32,bytes32) taskResponseMetadata, (uint256,uint256)[] pubkeysOfNonSigningOperators) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) RaiseAndResolveChallenge(task IIncredibleSquaringTaskManagerTask, taskResponse IIncredibleSquaringTaskManagerTaskResponse, taskResponseMetadata IIncredibleSquaringTaskManagerTaskResponseMetadata, pubkeysOfNonSigningOperators []BN254G1Point) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.RaiseAndResolveChallenge(&_ContractIncredibleSquaringTaskManager.TransactOpts, task, taskResponse, taskResponseMetadata, pubkeysOfNonSigningOperators) +} + +// RaiseAndResolveChallenge is a paid mutator transaction binding the contract method 0x6b532e9e. +// +// Solidity: function raiseAndResolveChallenge((uint256,uint32,bytes,uint32) task, (uint32,uint256) taskResponse, (uint32,bytes32) taskResponseMetadata, (uint256,uint256)[] pubkeysOfNonSigningOperators) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorSession) RaiseAndResolveChallenge(task IIncredibleSquaringTaskManagerTask, taskResponse IIncredibleSquaringTaskManagerTaskResponse, taskResponseMetadata IIncredibleSquaringTaskManagerTaskResponseMetadata, pubkeysOfNonSigningOperators []BN254G1Point) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.RaiseAndResolveChallenge(&_ContractIncredibleSquaringTaskManager.TransactOpts, task, taskResponse, taskResponseMetadata, pubkeysOfNonSigningOperators) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) RenounceOwnership() (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.RenounceOwnership(&_ContractIncredibleSquaringTaskManager.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.RenounceOwnership(&_ContractIncredibleSquaringTaskManager.TransactOpts) +} + +// RespondToTask is a paid mutator transaction binding the contract method 0x5baec9a0. +// +// Solidity: function respondToTask((uint256,uint32,bytes,uint32) task, (uint32,uint256) taskResponse, (uint32[],(uint256,uint256)[],(uint256,uint256)[],(uint256[2],uint256[2]),(uint256,uint256),uint32[],uint32[],uint32[][]) nonSignerStakesAndSignature) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactor) RespondToTask(opts *bind.TransactOpts, task IIncredibleSquaringTaskManagerTask, taskResponse IIncredibleSquaringTaskManagerTaskResponse, nonSignerStakesAndSignature IBLSSignatureCheckerNonSignerStakesAndSignature) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.contract.Transact(opts, "respondToTask", task, taskResponse, nonSignerStakesAndSignature) +} + +// RespondToTask is a paid mutator transaction binding the contract method 0x5baec9a0. +// +// Solidity: function respondToTask((uint256,uint32,bytes,uint32) task, (uint32,uint256) taskResponse, (uint32[],(uint256,uint256)[],(uint256,uint256)[],(uint256[2],uint256[2]),(uint256,uint256),uint32[],uint32[],uint32[][]) nonSignerStakesAndSignature) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) RespondToTask(task IIncredibleSquaringTaskManagerTask, taskResponse IIncredibleSquaringTaskManagerTaskResponse, nonSignerStakesAndSignature IBLSSignatureCheckerNonSignerStakesAndSignature) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.RespondToTask(&_ContractIncredibleSquaringTaskManager.TransactOpts, task, taskResponse, nonSignerStakesAndSignature) +} + +// RespondToTask is a paid mutator transaction binding the contract method 0x5baec9a0. +// +// Solidity: function respondToTask((uint256,uint32,bytes,uint32) task, (uint32,uint256) taskResponse, (uint32[],(uint256,uint256)[],(uint256,uint256)[],(uint256[2],uint256[2]),(uint256,uint256),uint32[],uint32[],uint32[][]) nonSignerStakesAndSignature) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorSession) RespondToTask(task IIncredibleSquaringTaskManagerTask, taskResponse IIncredibleSquaringTaskManagerTaskResponse, nonSignerStakesAndSignature IBLSSignatureCheckerNonSignerStakesAndSignature) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.RespondToTask(&_ContractIncredibleSquaringTaskManager.TransactOpts, task, taskResponse, nonSignerStakesAndSignature) +} + +// SetPauserRegistry is a paid mutator transaction binding the contract method 0x10d67a2f. +// +// Solidity: function setPauserRegistry(address newPauserRegistry) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactor) SetPauserRegistry(opts *bind.TransactOpts, newPauserRegistry common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.contract.Transact(opts, "setPauserRegistry", newPauserRegistry) +} + +// SetPauserRegistry is a paid mutator transaction binding the contract method 0x10d67a2f. +// +// Solidity: function setPauserRegistry(address newPauserRegistry) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) SetPauserRegistry(newPauserRegistry common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.SetPauserRegistry(&_ContractIncredibleSquaringTaskManager.TransactOpts, newPauserRegistry) +} + +// SetPauserRegistry is a paid mutator transaction binding the contract method 0x10d67a2f. +// +// Solidity: function setPauserRegistry(address newPauserRegistry) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorSession) SetPauserRegistry(newPauserRegistry common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.SetPauserRegistry(&_ContractIncredibleSquaringTaskManager.TransactOpts, newPauserRegistry) +} + +// SetStaleStakesForbidden is a paid mutator transaction binding the contract method 0x416c7e5e. +// +// Solidity: function setStaleStakesForbidden(bool value) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactor) SetStaleStakesForbidden(opts *bind.TransactOpts, value bool) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.contract.Transact(opts, "setStaleStakesForbidden", value) +} + +// SetStaleStakesForbidden is a paid mutator transaction binding the contract method 0x416c7e5e. +// +// Solidity: function setStaleStakesForbidden(bool value) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) SetStaleStakesForbidden(value bool) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.SetStaleStakesForbidden(&_ContractIncredibleSquaringTaskManager.TransactOpts, value) +} + +// SetStaleStakesForbidden is a paid mutator transaction binding the contract method 0x416c7e5e. +// +// Solidity: function setStaleStakesForbidden(bool value) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorSession) SetStaleStakesForbidden(value bool) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.SetStaleStakesForbidden(&_ContractIncredibleSquaringTaskManager.TransactOpts, value) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.TransferOwnership(&_ContractIncredibleSquaringTaskManager.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.TransferOwnership(&_ContractIncredibleSquaringTaskManager.TransactOpts, newOwner) +} + +// Unpause is a paid mutator transaction binding the contract method 0xfabc1cbc. +// +// Solidity: function unpause(uint256 newPausedStatus) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactor) Unpause(opts *bind.TransactOpts, newPausedStatus *big.Int) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.contract.Transact(opts, "unpause", newPausedStatus) +} + +// Unpause is a paid mutator transaction binding the contract method 0xfabc1cbc. +// +// Solidity: function unpause(uint256 newPausedStatus) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerSession) Unpause(newPausedStatus *big.Int) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Unpause(&_ContractIncredibleSquaringTaskManager.TransactOpts, newPausedStatus) +} + +// Unpause is a paid mutator transaction binding the contract method 0xfabc1cbc. +// +// Solidity: function unpause(uint256 newPausedStatus) returns() +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerTransactorSession) Unpause(newPausedStatus *big.Int) (*types.Transaction, error) { + return _ContractIncredibleSquaringTaskManager.Contract.Unpause(&_ContractIncredibleSquaringTaskManager.TransactOpts, newPausedStatus) +} + +// ContractIncredibleSquaringTaskManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerInitializedIterator struct { + Event *ContractIncredibleSquaringTaskManagerInitialized // 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 *ContractIncredibleSquaringTaskManagerInitializedIterator) 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(ContractIncredibleSquaringTaskManagerInitialized) + 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(ContractIncredibleSquaringTaskManagerInitialized) + 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 *ContractIncredibleSquaringTaskManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringTaskManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringTaskManagerInitialized represents a Initialized event raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerInitialized 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 (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*ContractIncredibleSquaringTaskManagerInitializedIterator, error) { + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerInitializedIterator{contract: _ContractIncredibleSquaringTaskManager.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 (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringTaskManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _ContractIncredibleSquaringTaskManager.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(ContractIncredibleSquaringTaskManagerInitialized) + if err := _ContractIncredibleSquaringTaskManager.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 (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) ParseInitialized(log types.Log) (*ContractIncredibleSquaringTaskManagerInitialized, error) { + event := new(ContractIncredibleSquaringTaskManagerInitialized) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractIncredibleSquaringTaskManagerNewTaskCreatedIterator is returned from FilterNewTaskCreated and is used to iterate over the raw logs and unpacked data for NewTaskCreated events raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerNewTaskCreatedIterator struct { + Event *ContractIncredibleSquaringTaskManagerNewTaskCreated // 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 *ContractIncredibleSquaringTaskManagerNewTaskCreatedIterator) 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(ContractIncredibleSquaringTaskManagerNewTaskCreated) + 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(ContractIncredibleSquaringTaskManagerNewTaskCreated) + 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 *ContractIncredibleSquaringTaskManagerNewTaskCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringTaskManagerNewTaskCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringTaskManagerNewTaskCreated represents a NewTaskCreated event raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerNewTaskCreated struct { + TaskIndex uint32 + Task IIncredibleSquaringTaskManagerTask + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNewTaskCreated is a free log retrieval operation binding the contract event 0x1695b8d06ec800b4615e745cfb5bd00c1f2875615d42925c3b5afa543bb24c48. +// +// Solidity: event NewTaskCreated(uint32 indexed taskIndex, (uint256,uint32,bytes,uint32) task) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) FilterNewTaskCreated(opts *bind.FilterOpts, taskIndex []uint32) (*ContractIncredibleSquaringTaskManagerNewTaskCreatedIterator, error) { + + var taskIndexRule []interface{} + for _, taskIndexItem := range taskIndex { + taskIndexRule = append(taskIndexRule, taskIndexItem) + } + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.FilterLogs(opts, "NewTaskCreated", taskIndexRule) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerNewTaskCreatedIterator{contract: _ContractIncredibleSquaringTaskManager.contract, event: "NewTaskCreated", logs: logs, sub: sub}, nil +} + +// WatchNewTaskCreated is a free log subscription operation binding the contract event 0x1695b8d06ec800b4615e745cfb5bd00c1f2875615d42925c3b5afa543bb24c48. +// +// Solidity: event NewTaskCreated(uint32 indexed taskIndex, (uint256,uint32,bytes,uint32) task) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) WatchNewTaskCreated(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringTaskManagerNewTaskCreated, taskIndex []uint32) (event.Subscription, error) { + + var taskIndexRule []interface{} + for _, taskIndexItem := range taskIndex { + taskIndexRule = append(taskIndexRule, taskIndexItem) + } + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.WatchLogs(opts, "NewTaskCreated", taskIndexRule) + 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(ContractIncredibleSquaringTaskManagerNewTaskCreated) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "NewTaskCreated", 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 +} + +// ParseNewTaskCreated is a log parse operation binding the contract event 0x1695b8d06ec800b4615e745cfb5bd00c1f2875615d42925c3b5afa543bb24c48. +// +// Solidity: event NewTaskCreated(uint32 indexed taskIndex, (uint256,uint32,bytes,uint32) task) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) ParseNewTaskCreated(log types.Log) (*ContractIncredibleSquaringTaskManagerNewTaskCreated, error) { + event := new(ContractIncredibleSquaringTaskManagerNewTaskCreated) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "NewTaskCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractIncredibleSquaringTaskManagerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerOwnershipTransferredIterator struct { + Event *ContractIncredibleSquaringTaskManagerOwnershipTransferred // 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 *ContractIncredibleSquaringTaskManagerOwnershipTransferredIterator) 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(ContractIncredibleSquaringTaskManagerOwnershipTransferred) + 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(ContractIncredibleSquaringTaskManagerOwnershipTransferred) + 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 *ContractIncredibleSquaringTaskManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringTaskManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringTaskManagerOwnershipTransferred represents a OwnershipTransferred event raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerOwnershipTransferred 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 (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ContractIncredibleSquaringTaskManagerOwnershipTransferredIterator, 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 := _ContractIncredibleSquaringTaskManager.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerOwnershipTransferredIterator{contract: _ContractIncredibleSquaringTaskManager.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 (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringTaskManagerOwnershipTransferred, 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 := _ContractIncredibleSquaringTaskManager.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(ContractIncredibleSquaringTaskManagerOwnershipTransferred) + if err := _ContractIncredibleSquaringTaskManager.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 (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) ParseOwnershipTransferred(log types.Log) (*ContractIncredibleSquaringTaskManagerOwnershipTransferred, error) { + event := new(ContractIncredibleSquaringTaskManagerOwnershipTransferred) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractIncredibleSquaringTaskManagerPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerPausedIterator struct { + Event *ContractIncredibleSquaringTaskManagerPaused // 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 *ContractIncredibleSquaringTaskManagerPausedIterator) 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(ContractIncredibleSquaringTaskManagerPaused) + 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(ContractIncredibleSquaringTaskManagerPaused) + 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 *ContractIncredibleSquaringTaskManagerPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringTaskManagerPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringTaskManagerPaused represents a Paused event raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerPaused struct { + Account common.Address + NewPausedStatus *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPaused is a free log retrieval operation binding the contract event 0xab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d. +// +// Solidity: event Paused(address indexed account, uint256 newPausedStatus) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) FilterPaused(opts *bind.FilterOpts, account []common.Address) (*ContractIncredibleSquaringTaskManagerPausedIterator, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.FilterLogs(opts, "Paused", accountRule) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerPausedIterator{contract: _ContractIncredibleSquaringTaskManager.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +// WatchPaused is a free log subscription operation binding the contract event 0xab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d. +// +// Solidity: event Paused(address indexed account, uint256 newPausedStatus) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringTaskManagerPaused, account []common.Address) (event.Subscription, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.WatchLogs(opts, "Paused", 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(ContractIncredibleSquaringTaskManagerPaused) + if err := _ContractIncredibleSquaringTaskManager.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 0xab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d. +// +// Solidity: event Paused(address indexed account, uint256 newPausedStatus) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) ParsePaused(log types.Log) (*ContractIncredibleSquaringTaskManagerPaused, error) { + event := new(ContractIncredibleSquaringTaskManagerPaused) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractIncredibleSquaringTaskManagerPauserRegistrySetIterator is returned from FilterPauserRegistrySet and is used to iterate over the raw logs and unpacked data for PauserRegistrySet events raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerPauserRegistrySetIterator struct { + Event *ContractIncredibleSquaringTaskManagerPauserRegistrySet // 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 *ContractIncredibleSquaringTaskManagerPauserRegistrySetIterator) 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(ContractIncredibleSquaringTaskManagerPauserRegistrySet) + 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(ContractIncredibleSquaringTaskManagerPauserRegistrySet) + 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 *ContractIncredibleSquaringTaskManagerPauserRegistrySetIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringTaskManagerPauserRegistrySetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringTaskManagerPauserRegistrySet represents a PauserRegistrySet event raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerPauserRegistrySet struct { + PauserRegistry common.Address + NewPauserRegistry common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPauserRegistrySet is a free log retrieval operation binding the contract event 0x6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6. +// +// Solidity: event PauserRegistrySet(address pauserRegistry, address newPauserRegistry) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) FilterPauserRegistrySet(opts *bind.FilterOpts) (*ContractIncredibleSquaringTaskManagerPauserRegistrySetIterator, error) { + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.FilterLogs(opts, "PauserRegistrySet") + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerPauserRegistrySetIterator{contract: _ContractIncredibleSquaringTaskManager.contract, event: "PauserRegistrySet", logs: logs, sub: sub}, nil +} + +// WatchPauserRegistrySet is a free log subscription operation binding the contract event 0x6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6. +// +// Solidity: event PauserRegistrySet(address pauserRegistry, address newPauserRegistry) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) WatchPauserRegistrySet(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringTaskManagerPauserRegistrySet) (event.Subscription, error) { + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.WatchLogs(opts, "PauserRegistrySet") + 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(ContractIncredibleSquaringTaskManagerPauserRegistrySet) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "PauserRegistrySet", 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 +} + +// ParsePauserRegistrySet is a log parse operation binding the contract event 0x6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6. +// +// Solidity: event PauserRegistrySet(address pauserRegistry, address newPauserRegistry) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) ParsePauserRegistrySet(log types.Log) (*ContractIncredibleSquaringTaskManagerPauserRegistrySet, error) { + event := new(ContractIncredibleSquaringTaskManagerPauserRegistrySet) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "PauserRegistrySet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdateIterator is returned from FilterStaleStakesForbiddenUpdate and is used to iterate over the raw logs and unpacked data for StaleStakesForbiddenUpdate events raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdateIterator struct { + Event *ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdate // 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 *ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdateIterator) 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(ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdate) + 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(ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdate) + 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 *ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdateIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdateIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdate represents a StaleStakesForbiddenUpdate event raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdate struct { + Value bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStaleStakesForbiddenUpdate is a free log retrieval operation binding the contract event 0x40e4ed880a29e0f6ddce307457fb75cddf4feef7d3ecb0301bfdf4976a0e2dfc. +// +// Solidity: event StaleStakesForbiddenUpdate(bool value) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) FilterStaleStakesForbiddenUpdate(opts *bind.FilterOpts) (*ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdateIterator, error) { + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.FilterLogs(opts, "StaleStakesForbiddenUpdate") + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdateIterator{contract: _ContractIncredibleSquaringTaskManager.contract, event: "StaleStakesForbiddenUpdate", logs: logs, sub: sub}, nil +} + +// WatchStaleStakesForbiddenUpdate is a free log subscription operation binding the contract event 0x40e4ed880a29e0f6ddce307457fb75cddf4feef7d3ecb0301bfdf4976a0e2dfc. +// +// Solidity: event StaleStakesForbiddenUpdate(bool value) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) WatchStaleStakesForbiddenUpdate(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdate) (event.Subscription, error) { + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.WatchLogs(opts, "StaleStakesForbiddenUpdate") + 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(ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdate) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "StaleStakesForbiddenUpdate", 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 +} + +// ParseStaleStakesForbiddenUpdate is a log parse operation binding the contract event 0x40e4ed880a29e0f6ddce307457fb75cddf4feef7d3ecb0301bfdf4976a0e2dfc. +// +// Solidity: event StaleStakesForbiddenUpdate(bool value) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) ParseStaleStakesForbiddenUpdate(log types.Log) (*ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdate, error) { + event := new(ContractIncredibleSquaringTaskManagerStaleStakesForbiddenUpdate) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "StaleStakesForbiddenUpdate", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfullyIterator is returned from FilterTaskChallengedSuccessfully and is used to iterate over the raw logs and unpacked data for TaskChallengedSuccessfully events raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfullyIterator struct { + Event *ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfully // 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 *ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfullyIterator) 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(ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfully) + 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(ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfully) + 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 *ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfullyIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfullyIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfully represents a TaskChallengedSuccessfully event raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfully struct { + TaskIndex uint32 + Challenger common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTaskChallengedSuccessfully is a free log retrieval operation binding the contract event 0xc20d1bb0f1623680306b83d4ff4bb99a2beb9d86d97832f3ca40fd13a29df1ec. +// +// Solidity: event TaskChallengedSuccessfully(uint32 indexed taskIndex, address indexed challenger) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) FilterTaskChallengedSuccessfully(opts *bind.FilterOpts, taskIndex []uint32, challenger []common.Address) (*ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfullyIterator, error) { + + var taskIndexRule []interface{} + for _, taskIndexItem := range taskIndex { + taskIndexRule = append(taskIndexRule, taskIndexItem) + } + var challengerRule []interface{} + for _, challengerItem := range challenger { + challengerRule = append(challengerRule, challengerItem) + } + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.FilterLogs(opts, "TaskChallengedSuccessfully", taskIndexRule, challengerRule) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfullyIterator{contract: _ContractIncredibleSquaringTaskManager.contract, event: "TaskChallengedSuccessfully", logs: logs, sub: sub}, nil +} + +// WatchTaskChallengedSuccessfully is a free log subscription operation binding the contract event 0xc20d1bb0f1623680306b83d4ff4bb99a2beb9d86d97832f3ca40fd13a29df1ec. +// +// Solidity: event TaskChallengedSuccessfully(uint32 indexed taskIndex, address indexed challenger) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) WatchTaskChallengedSuccessfully(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfully, taskIndex []uint32, challenger []common.Address) (event.Subscription, error) { + + var taskIndexRule []interface{} + for _, taskIndexItem := range taskIndex { + taskIndexRule = append(taskIndexRule, taskIndexItem) + } + var challengerRule []interface{} + for _, challengerItem := range challenger { + challengerRule = append(challengerRule, challengerItem) + } + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.WatchLogs(opts, "TaskChallengedSuccessfully", taskIndexRule, challengerRule) + 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(ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfully) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "TaskChallengedSuccessfully", 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 +} + +// ParseTaskChallengedSuccessfully is a log parse operation binding the contract event 0xc20d1bb0f1623680306b83d4ff4bb99a2beb9d86d97832f3ca40fd13a29df1ec. +// +// Solidity: event TaskChallengedSuccessfully(uint32 indexed taskIndex, address indexed challenger) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) ParseTaskChallengedSuccessfully(log types.Log) (*ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfully, error) { + event := new(ContractIncredibleSquaringTaskManagerTaskChallengedSuccessfully) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "TaskChallengedSuccessfully", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfullyIterator is returned from FilterTaskChallengedUnsuccessfully and is used to iterate over the raw logs and unpacked data for TaskChallengedUnsuccessfully events raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfullyIterator struct { + Event *ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfully // 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 *ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfullyIterator) 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(ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfully) + 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(ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfully) + 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 *ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfullyIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfullyIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfully represents a TaskChallengedUnsuccessfully event raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfully struct { + TaskIndex uint32 + Challenger common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTaskChallengedUnsuccessfully is a free log retrieval operation binding the contract event 0xfd3e26beeb5967fc5a57a0446914eabc45b4aa474c67a51b4b5160cac60ddb05. +// +// Solidity: event TaskChallengedUnsuccessfully(uint32 indexed taskIndex, address indexed challenger) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) FilterTaskChallengedUnsuccessfully(opts *bind.FilterOpts, taskIndex []uint32, challenger []common.Address) (*ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfullyIterator, error) { + + var taskIndexRule []interface{} + for _, taskIndexItem := range taskIndex { + taskIndexRule = append(taskIndexRule, taskIndexItem) + } + var challengerRule []interface{} + for _, challengerItem := range challenger { + challengerRule = append(challengerRule, challengerItem) + } + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.FilterLogs(opts, "TaskChallengedUnsuccessfully", taskIndexRule, challengerRule) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfullyIterator{contract: _ContractIncredibleSquaringTaskManager.contract, event: "TaskChallengedUnsuccessfully", logs: logs, sub: sub}, nil +} + +// WatchTaskChallengedUnsuccessfully is a free log subscription operation binding the contract event 0xfd3e26beeb5967fc5a57a0446914eabc45b4aa474c67a51b4b5160cac60ddb05. +// +// Solidity: event TaskChallengedUnsuccessfully(uint32 indexed taskIndex, address indexed challenger) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) WatchTaskChallengedUnsuccessfully(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfully, taskIndex []uint32, challenger []common.Address) (event.Subscription, error) { + + var taskIndexRule []interface{} + for _, taskIndexItem := range taskIndex { + taskIndexRule = append(taskIndexRule, taskIndexItem) + } + var challengerRule []interface{} + for _, challengerItem := range challenger { + challengerRule = append(challengerRule, challengerItem) + } + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.WatchLogs(opts, "TaskChallengedUnsuccessfully", taskIndexRule, challengerRule) + 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(ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfully) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "TaskChallengedUnsuccessfully", 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 +} + +// ParseTaskChallengedUnsuccessfully is a log parse operation binding the contract event 0xfd3e26beeb5967fc5a57a0446914eabc45b4aa474c67a51b4b5160cac60ddb05. +// +// Solidity: event TaskChallengedUnsuccessfully(uint32 indexed taskIndex, address indexed challenger) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) ParseTaskChallengedUnsuccessfully(log types.Log) (*ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfully, error) { + event := new(ContractIncredibleSquaringTaskManagerTaskChallengedUnsuccessfully) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "TaskChallengedUnsuccessfully", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractIncredibleSquaringTaskManagerTaskCompletedIterator is returned from FilterTaskCompleted and is used to iterate over the raw logs and unpacked data for TaskCompleted events raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerTaskCompletedIterator struct { + Event *ContractIncredibleSquaringTaskManagerTaskCompleted // 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 *ContractIncredibleSquaringTaskManagerTaskCompletedIterator) 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(ContractIncredibleSquaringTaskManagerTaskCompleted) + 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(ContractIncredibleSquaringTaskManagerTaskCompleted) + 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 *ContractIncredibleSquaringTaskManagerTaskCompletedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringTaskManagerTaskCompletedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringTaskManagerTaskCompleted represents a TaskCompleted event raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerTaskCompleted struct { + TaskIndex uint32 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTaskCompleted is a free log retrieval operation binding the contract event 0x9a144f228a931b9d0d1696fbcdaf310b24b5d2d21e799db623fc986a0f547430. +// +// Solidity: event TaskCompleted(uint32 indexed taskIndex) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) FilterTaskCompleted(opts *bind.FilterOpts, taskIndex []uint32) (*ContractIncredibleSquaringTaskManagerTaskCompletedIterator, error) { + + var taskIndexRule []interface{} + for _, taskIndexItem := range taskIndex { + taskIndexRule = append(taskIndexRule, taskIndexItem) + } + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.FilterLogs(opts, "TaskCompleted", taskIndexRule) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerTaskCompletedIterator{contract: _ContractIncredibleSquaringTaskManager.contract, event: "TaskCompleted", logs: logs, sub: sub}, nil +} + +// WatchTaskCompleted is a free log subscription operation binding the contract event 0x9a144f228a931b9d0d1696fbcdaf310b24b5d2d21e799db623fc986a0f547430. +// +// Solidity: event TaskCompleted(uint32 indexed taskIndex) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) WatchTaskCompleted(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringTaskManagerTaskCompleted, taskIndex []uint32) (event.Subscription, error) { + + var taskIndexRule []interface{} + for _, taskIndexItem := range taskIndex { + taskIndexRule = append(taskIndexRule, taskIndexItem) + } + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.WatchLogs(opts, "TaskCompleted", taskIndexRule) + 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(ContractIncredibleSquaringTaskManagerTaskCompleted) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "TaskCompleted", 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 +} + +// ParseTaskCompleted is a log parse operation binding the contract event 0x9a144f228a931b9d0d1696fbcdaf310b24b5d2d21e799db623fc986a0f547430. +// +// Solidity: event TaskCompleted(uint32 indexed taskIndex) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) ParseTaskCompleted(log types.Log) (*ContractIncredibleSquaringTaskManagerTaskCompleted, error) { + event := new(ContractIncredibleSquaringTaskManagerTaskCompleted) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "TaskCompleted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractIncredibleSquaringTaskManagerTaskRespondedIterator is returned from FilterTaskResponded and is used to iterate over the raw logs and unpacked data for TaskResponded events raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerTaskRespondedIterator struct { + Event *ContractIncredibleSquaringTaskManagerTaskResponded // 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 *ContractIncredibleSquaringTaskManagerTaskRespondedIterator) 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(ContractIncredibleSquaringTaskManagerTaskResponded) + 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(ContractIncredibleSquaringTaskManagerTaskResponded) + 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 *ContractIncredibleSquaringTaskManagerTaskRespondedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringTaskManagerTaskRespondedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringTaskManagerTaskResponded represents a TaskResponded event raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerTaskResponded struct { + TaskResponse IIncredibleSquaringTaskManagerTaskResponse + TaskResponseMetadata IIncredibleSquaringTaskManagerTaskResponseMetadata + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTaskResponded is a free log retrieval operation binding the contract event 0x349c1ee60e4e8972ee9dba642c1774543d5c4136879b7f4caaf04bf81a487a2a. +// +// Solidity: event TaskResponded((uint32,uint256) taskResponse, (uint32,bytes32) taskResponseMetadata) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) FilterTaskResponded(opts *bind.FilterOpts) (*ContractIncredibleSquaringTaskManagerTaskRespondedIterator, error) { + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.FilterLogs(opts, "TaskResponded") + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerTaskRespondedIterator{contract: _ContractIncredibleSquaringTaskManager.contract, event: "TaskResponded", logs: logs, sub: sub}, nil +} + +// WatchTaskResponded is a free log subscription operation binding the contract event 0x349c1ee60e4e8972ee9dba642c1774543d5c4136879b7f4caaf04bf81a487a2a. +// +// Solidity: event TaskResponded((uint32,uint256) taskResponse, (uint32,bytes32) taskResponseMetadata) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) WatchTaskResponded(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringTaskManagerTaskResponded) (event.Subscription, error) { + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.WatchLogs(opts, "TaskResponded") + 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(ContractIncredibleSquaringTaskManagerTaskResponded) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "TaskResponded", 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 +} + +// ParseTaskResponded is a log parse operation binding the contract event 0x349c1ee60e4e8972ee9dba642c1774543d5c4136879b7f4caaf04bf81a487a2a. +// +// Solidity: event TaskResponded((uint32,uint256) taskResponse, (uint32,bytes32) taskResponseMetadata) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) ParseTaskResponded(log types.Log) (*ContractIncredibleSquaringTaskManagerTaskResponded, error) { + event := new(ContractIncredibleSquaringTaskManagerTaskResponded) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "TaskResponded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ContractIncredibleSquaringTaskManagerUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerUnpausedIterator struct { + Event *ContractIncredibleSquaringTaskManagerUnpaused // 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 *ContractIncredibleSquaringTaskManagerUnpausedIterator) 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(ContractIncredibleSquaringTaskManagerUnpaused) + 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(ContractIncredibleSquaringTaskManagerUnpaused) + 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 *ContractIncredibleSquaringTaskManagerUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractIncredibleSquaringTaskManagerUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractIncredibleSquaringTaskManagerUnpaused represents a Unpaused event raised by the ContractIncredibleSquaringTaskManager contract. +type ContractIncredibleSquaringTaskManagerUnpaused struct { + Account common.Address + NewPausedStatus *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnpaused is a free log retrieval operation binding the contract event 0x3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c. +// +// Solidity: event Unpaused(address indexed account, uint256 newPausedStatus) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) FilterUnpaused(opts *bind.FilterOpts, account []common.Address) (*ContractIncredibleSquaringTaskManagerUnpausedIterator, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.FilterLogs(opts, "Unpaused", accountRule) + if err != nil { + return nil, err + } + return &ContractIncredibleSquaringTaskManagerUnpausedIterator{contract: _ContractIncredibleSquaringTaskManager.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +// WatchUnpaused is a free log subscription operation binding the contract event 0x3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c. +// +// Solidity: event Unpaused(address indexed account, uint256 newPausedStatus) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *ContractIncredibleSquaringTaskManagerUnpaused, account []common.Address) (event.Subscription, error) { + + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + + logs, sub, err := _ContractIncredibleSquaringTaskManager.contract.WatchLogs(opts, "Unpaused", 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(ContractIncredibleSquaringTaskManagerUnpaused) + if err := _ContractIncredibleSquaringTaskManager.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 0x3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c. +// +// Solidity: event Unpaused(address indexed account, uint256 newPausedStatus) +func (_ContractIncredibleSquaringTaskManager *ContractIncredibleSquaringTaskManagerFilterer) ParseUnpaused(log types.Log) (*ContractIncredibleSquaringTaskManagerUnpaused, error) { + event := new(ContractIncredibleSquaringTaskManagerUnpaused) + if err := _ContractIncredibleSquaringTaskManager.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/temp-incredible-squaring-avs/contracts/foundry.toml b/temp-incredible-squaring-avs/contracts/foundry.toml new file mode 100644 index 0000000..16b72d3 --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/foundry.toml @@ -0,0 +1,30 @@ +[profile.default] +src = "src" +out = "out" +libs = ["lib"] +fs_permissions = [{ access = "read-write", path = "./"}] + +remappings = [ + "@eigenlayer/=lib/eigenlayer-middleware/lib/eigenlayer-contracts/src/", + "@eigenlayer-scripts/=lib/eigenlayer-middleware/lib/eigenlayer-contracts/script/", + "@eigenlayer-middleware/=lib/eigenlayer-middleware/", + "@credible-squaring/=src/", + "@openzeppelin/=lib/eigenlayer-middleware/lib/eigenlayer-contracts/lib/openzeppelin-contracts/", + "@openzeppelin-upgrades/=lib/eigenlayer-middleware/lib/eigenlayer-contracts/lib/openzeppelin-contracts-upgradeable/", + "forge-std/=lib/forge-std/src/" +] + +gas_reports = ["*"] + +# A list of ignored solc error codes + +# Enables or disables the optimizer +optimizer = true +# The number of optimizer runs +optimizer_runs = 200 +# Whether or not to use the Yul intermediate representation compilation pipeline +via_ir = false +# Override the Solidity version (this overrides `auto_detect_solc`) +solc_version = '0.8.12' + +# See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/temp-incredible-squaring-avs/contracts/generate-go-bindings.sh b/temp-incredible-squaring-avs/contracts/generate-go-bindings.sh new file mode 100755 index 0000000..f48fab8 --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/generate-go-bindings.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +function create_binding { + contract_dir=$1 + contract=$2 + binding_dir=$3 + echo "generating bindings for" $contract + mkdir -p $binding_dir/${contract} + contract_json="$contract_dir/out/${contract}.sol/${contract}.json" + solc_abi=$(cat ${contract_json} | jq -r '.abi') + solc_bin=$(cat ${contract_json} | jq -r '.bytecode.object') + + mkdir -p data + echo ${solc_abi} >data/tmp.abi + echo ${solc_bin} >data/tmp.bin + + rm -f $binding_dir/${contract}/binding.go + abigen --bin=data/tmp.bin --abi=data/tmp.abi --pkg=contract${contract} --out=$binding_dir/${contract}/binding.go + rm -rf ../data/tmp.abi ../data/tmp.bin +} + +rm -rf bindings/* +forge clean +forge build + +avs_service_contracts="IncredibleSquaringServiceManager IncredibleSquaringTaskManager" +for contract in $avs_service_contracts; do + create_binding . $contract ./bindings +done + +create_binding . ERC20Mock ./bindings diff --git a/temp-incredible-squaring-avs/contracts/script/IncredibleSquaringDeployer.s.sol b/temp-incredible-squaring-avs/contracts/script/IncredibleSquaringDeployer.s.sol new file mode 100644 index 0000000..e455112 --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/script/IncredibleSquaringDeployer.s.sol @@ -0,0 +1,454 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.9; + +import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; + +import "@eigenlayer/contracts/permissions/PauserRegistry.sol"; +import {IDelegationManager} from "@eigenlayer/contracts/interfaces/IDelegationManager.sol"; +import {IAVSDirectory} from "@eigenlayer/contracts/interfaces/IAVSDirectory.sol"; +import {IStrategyManager, IStrategy} from "@eigenlayer/contracts/interfaces/IStrategyManager.sol"; +import {ISlasher} from "@eigenlayer/contracts/interfaces/ISlasher.sol"; +import {StrategyBaseTVLLimits} from "@eigenlayer/contracts/strategies/StrategyBaseTVLLimits.sol"; +import "@eigenlayer/test/mocks/EmptyContract.sol"; + +import "@eigenlayer-middleware/src/RegistryCoordinator.sol" as regcoord; +import {IBLSApkRegistry, IIndexRegistry, IStakeRegistry} from "@eigenlayer-middleware/src/RegistryCoordinator.sol"; +import {BLSApkRegistry} from "@eigenlayer-middleware/src/BLSApkRegistry.sol"; +import {IndexRegistry} from "@eigenlayer-middleware/src/IndexRegistry.sol"; +import {StakeRegistry} from "@eigenlayer-middleware/src/StakeRegistry.sol"; +import "@eigenlayer-middleware/src/OperatorStateRetriever.sol"; + +import {IncredibleSquaringServiceManager, IServiceManager} from "../src/IncredibleSquaringServiceManager.sol"; +import {IncredibleSquaringTaskManager} from "../src/IncredibleSquaringTaskManager.sol"; +import {IIncredibleSquaringTaskManager} from "../src/IIncredibleSquaringTaskManager.sol"; +import "../src/ERC20Mock.sol"; + +import {Utils} from "./utils/Utils.sol"; + +import "forge-std/Test.sol"; +import "forge-std/Script.sol"; +import "forge-std/StdJson.sol"; +import "forge-std/console.sol"; + +// # To deploy and verify our contract +// forge script script/CredibleSquaringDeployer.s.sol:CredibleSquaringDeployer --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast -vvvv +contract IncredibleSquaringDeployer is Script, Utils { + // DEPLOYMENT CONSTANTS + uint256 public constant QUORUM_THRESHOLD_PERCENTAGE = 100; + uint32 public constant TASK_RESPONSE_WINDOW_BLOCK = 30; + uint32 public constant TASK_DURATION_BLOCKS = 0; + // TODO: right now hardcoding these (this address is anvil's default address 9) + address public constant AGGREGATOR_ADDR = + 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720; + address public constant TASK_GENERATOR_ADDR = + 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720; + + // ERC20 and Strategy: we need to deploy this erc20, create a strategy for it, and whitelist this strategy in the strategymanager + + ERC20Mock public erc20Mock; + StrategyBaseTVLLimits public erc20MockStrategy; + + // Credible Squaring contracts + ProxyAdmin public incredibleSquaringProxyAdmin; + PauserRegistry public incredibleSquaringPauserReg; + + regcoord.RegistryCoordinator public registryCoordinator; + regcoord.IRegistryCoordinator public registryCoordinatorImplementation; + + IBLSApkRegistry public blsApkRegistry; + IBLSApkRegistry public blsApkRegistryImplementation; + + IIndexRegistry public indexRegistry; + IIndexRegistry public indexRegistryImplementation; + + IStakeRegistry public stakeRegistry; + IStakeRegistry public stakeRegistryImplementation; + + OperatorStateRetriever public operatorStateRetriever; + + IncredibleSquaringServiceManager public incredibleSquaringServiceManager; + IServiceManager public incredibleSquaringServiceManagerImplementation; + + IncredibleSquaringTaskManager public incredibleSquaringTaskManager; + IIncredibleSquaringTaskManager + public incredibleSquaringTaskManagerImplementation; + + function run() external { + // Eigenlayer contracts + string memory eigenlayerDeployedContracts = readOutput( + "eigenlayer_deployment_output" + ); + IStrategyManager strategyManager = IStrategyManager( + stdJson.readAddress( + eigenlayerDeployedContracts, + ".addresses.strategyManager" + ) + ); + IDelegationManager delegationManager = IDelegationManager( + stdJson.readAddress( + eigenlayerDeployedContracts, + ".addresses.delegation" + ) + ); + IAVSDirectory avsDirectory = IAVSDirectory( + stdJson.readAddress( + eigenlayerDeployedContracts, + ".addresses.avsDirectory" + ) + ); + ProxyAdmin eigenLayerProxyAdmin = ProxyAdmin( + stdJson.readAddress( + eigenlayerDeployedContracts, + ".addresses.eigenLayerProxyAdmin" + ) + ); + PauserRegistry eigenLayerPauserReg = PauserRegistry( + stdJson.readAddress( + eigenlayerDeployedContracts, + ".addresses.eigenLayerPauserReg" + ) + ); + StrategyBaseTVLLimits baseStrategyImplementation = StrategyBaseTVLLimits( + stdJson.readAddress( + eigenlayerDeployedContracts, + ".addresses.baseStrategyImplementation" + ) + ); + + address credibleSquaringCommunityMultisig = msg.sender; + address credibleSquaringPauser = msg.sender; + + vm.startBroadcast(); + _deployErc20AndStrategyAndWhitelistStrategy( + eigenLayerProxyAdmin, + eigenLayerPauserReg, + baseStrategyImplementation, + strategyManager + ); + _deployCredibleSquaringContracts( + delegationManager, + avsDirectory, + erc20MockStrategy, + credibleSquaringCommunityMultisig, + credibleSquaringPauser + ); + vm.stopBroadcast(); + } + + function _deployErc20AndStrategyAndWhitelistStrategy( + ProxyAdmin eigenLayerProxyAdmin, + PauserRegistry eigenLayerPauserReg, + StrategyBaseTVLLimits baseStrategyImplementation, + IStrategyManager strategyManager + ) internal { + erc20Mock = new ERC20Mock(); + // TODO(samlaf): any reason why we are using the strategybase with tvl limits instead of just using strategybase? + // the maxPerDeposit and maxDeposits below are just arbitrary values. + erc20MockStrategy = StrategyBaseTVLLimits( + address( + new TransparentUpgradeableProxy( + address(baseStrategyImplementation), + address(eigenLayerProxyAdmin), + abi.encodeWithSelector( + StrategyBaseTVLLimits.initialize.selector, + 1 ether, // maxPerDeposit + 100 ether, // maxDeposits + IERC20(erc20Mock), + eigenLayerPauserReg + ) + ) + ) + ); + IStrategy[] memory strats = new IStrategy[](1); + strats[0] = erc20MockStrategy; + bool[] memory thirdPartyTransfersForbiddenValues = new bool[](1); + thirdPartyTransfersForbiddenValues[0] = false; + strategyManager.addStrategiesToDepositWhitelist( + strats, + thirdPartyTransfersForbiddenValues + ); + } + + function _deployCredibleSquaringContracts( + IDelegationManager delegationManager, + IAVSDirectory avsDirectory, + IStrategy strat, + address incredibleSquaringCommunityMultisig, + address credibleSquaringPauser + ) internal { + // Adding this as a temporary fix to make the rest of the script work with a single strategy + // since it was originally written to work with an array of strategies + IStrategy[1] memory deployedStrategyArray = [strat]; + uint numStrategies = deployedStrategyArray.length; + + // deploy proxy admin for ability to upgrade proxy contracts + incredibleSquaringProxyAdmin = new ProxyAdmin(); + + // deploy pauser registry + { + address[] memory pausers = new address[](2); + pausers[0] = credibleSquaringPauser; + pausers[1] = incredibleSquaringCommunityMultisig; + incredibleSquaringPauserReg = new PauserRegistry( + pausers, + incredibleSquaringCommunityMultisig + ); + } + + EmptyContract emptyContract = new EmptyContract(); + + // hard-coded inputs + + /** + * First, deploy upgradeable proxy contracts that **will point** to the implementations. Since the implementation contracts are + * not yet deployed, we give these proxies an empty contract as the initial implementation, to act as if they have no code. + */ + incredibleSquaringServiceManager = IncredibleSquaringServiceManager( + address( + new TransparentUpgradeableProxy( + address(emptyContract), + address(incredibleSquaringProxyAdmin), + "" + ) + ) + ); + incredibleSquaringTaskManager = IncredibleSquaringTaskManager( + address( + new TransparentUpgradeableProxy( + address(emptyContract), + address(incredibleSquaringProxyAdmin), + "" + ) + ) + ); + registryCoordinator = regcoord.RegistryCoordinator( + address( + new TransparentUpgradeableProxy( + address(emptyContract), + address(incredibleSquaringProxyAdmin), + "" + ) + ) + ); + blsApkRegistry = IBLSApkRegistry( + address( + new TransparentUpgradeableProxy( + address(emptyContract), + address(incredibleSquaringProxyAdmin), + "" + ) + ) + ); + indexRegistry = IIndexRegistry( + address( + new TransparentUpgradeableProxy( + address(emptyContract), + address(incredibleSquaringProxyAdmin), + "" + ) + ) + ); + stakeRegistry = IStakeRegistry( + address( + new TransparentUpgradeableProxy( + address(emptyContract), + address(incredibleSquaringProxyAdmin), + "" + ) + ) + ); + + operatorStateRetriever = new OperatorStateRetriever(); + + // Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs + { + stakeRegistryImplementation = new StakeRegistry( + registryCoordinator, + delegationManager + ); + + incredibleSquaringProxyAdmin.upgrade( + TransparentUpgradeableProxy(payable(address(stakeRegistry))), + address(stakeRegistryImplementation) + ); + + blsApkRegistryImplementation = new BLSApkRegistry( + registryCoordinator + ); + + incredibleSquaringProxyAdmin.upgrade( + TransparentUpgradeableProxy(payable(address(blsApkRegistry))), + address(blsApkRegistryImplementation) + ); + + indexRegistryImplementation = new IndexRegistry( + registryCoordinator + ); + + incredibleSquaringProxyAdmin.upgrade( + TransparentUpgradeableProxy(payable(address(indexRegistry))), + address(indexRegistryImplementation) + ); + } + + registryCoordinatorImplementation = new regcoord.RegistryCoordinator( + incredibleSquaringServiceManager, + regcoord.IStakeRegistry(address(stakeRegistry)), + regcoord.IBLSApkRegistry(address(blsApkRegistry)), + regcoord.IIndexRegistry(address(indexRegistry)) + ); + + { + uint numQuorums = 1; + // for each quorum to setup, we need to define + // QuorumOperatorSetParam, minimumStakeForQuorum, and strategyParams + regcoord.IRegistryCoordinator.OperatorSetParam[] + memory quorumsOperatorSetParams = new regcoord.IRegistryCoordinator.OperatorSetParam[]( + numQuorums + ); + for (uint i = 0; i < numQuorums; i++) { + // hard code these for now + quorumsOperatorSetParams[i] = regcoord + .IRegistryCoordinator + .OperatorSetParam({ + maxOperatorCount: 10000, + kickBIPsOfOperatorStake: 15000, + kickBIPsOfTotalStake: 100 + }); + } + // set to 0 for every quorum + uint96[] memory quorumsMinimumStake = new uint96[](numQuorums); + IStakeRegistry.StrategyParams[][] + memory quorumsStrategyParams = new IStakeRegistry.StrategyParams[][]( + numQuorums + ); + for (uint i = 0; i < numQuorums; i++) { + quorumsStrategyParams[i] = new IStakeRegistry.StrategyParams[]( + numStrategies + ); + for (uint j = 0; j < numStrategies; j++) { + quorumsStrategyParams[i][j] = IStakeRegistry + .StrategyParams({ + strategy: deployedStrategyArray[j], + // setting this to 1 ether since the divisor is also 1 ether + // therefore this allows an operator to register with even just 1 token + // see https://github.com/Layr-Labs/eigenlayer-middleware/blob/m2-mainnet/src/StakeRegistry.sol#L484 + // weight += uint96(sharesAmount * strategyAndMultiplier.multiplier / WEIGHTING_DIVISOR); + multiplier: 1 ether + }); + } + } + incredibleSquaringProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy( + payable(address(registryCoordinator)) + ), + address(registryCoordinatorImplementation), + abi.encodeWithSelector( + regcoord.RegistryCoordinator.initialize.selector, + // we set churnApprover and ejector to communityMultisig because we don't need them + incredibleSquaringCommunityMultisig, + incredibleSquaringCommunityMultisig, + incredibleSquaringCommunityMultisig, + incredibleSquaringPauserReg, + 0, // 0 initialPausedStatus means everything unpaused + quorumsOperatorSetParams, + quorumsMinimumStake, + quorumsStrategyParams + ) + ); + } + + incredibleSquaringServiceManagerImplementation = new IncredibleSquaringServiceManager( + avsDirectory, + registryCoordinator, + stakeRegistry, + incredibleSquaringTaskManager + ); + // Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them. + incredibleSquaringProxyAdmin.upgrade( + TransparentUpgradeableProxy( + payable(address(incredibleSquaringServiceManager)) + ), + address(incredibleSquaringServiceManagerImplementation) + ); + + incredibleSquaringTaskManagerImplementation = new IncredibleSquaringTaskManager( + registryCoordinator, + TASK_RESPONSE_WINDOW_BLOCK + ); + + // Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them. + incredibleSquaringProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy( + payable(address(incredibleSquaringTaskManager)) + ), + address(incredibleSquaringTaskManagerImplementation), + abi.encodeWithSelector( + incredibleSquaringTaskManager.initialize.selector, + incredibleSquaringPauserReg, + incredibleSquaringCommunityMultisig, + AGGREGATOR_ADDR, + TASK_GENERATOR_ADDR + ) + ); + + // WRITE JSON DATA + string memory parent_object = "parent object"; + + string memory deployed_addresses = "addresses"; + vm.serializeAddress( + deployed_addresses, + "erc20Mock", + address(erc20Mock) + ); + vm.serializeAddress( + deployed_addresses, + "erc20MockStrategy", + address(erc20MockStrategy) + ); + vm.serializeAddress( + deployed_addresses, + "credibleSquaringServiceManager", + address(incredibleSquaringServiceManager) + ); + vm.serializeAddress( + deployed_addresses, + "credibleSquaringServiceManagerImplementation", + address(incredibleSquaringServiceManagerImplementation) + ); + vm.serializeAddress( + deployed_addresses, + "credibleSquaringTaskManager", + address(incredibleSquaringTaskManager) + ); + vm.serializeAddress( + deployed_addresses, + "credibleSquaringTaskManagerImplementation", + address(incredibleSquaringTaskManagerImplementation) + ); + vm.serializeAddress( + deployed_addresses, + "registryCoordinator", + address(registryCoordinator) + ); + vm.serializeAddress( + deployed_addresses, + "registryCoordinatorImplementation", + address(registryCoordinatorImplementation) + ); + string memory deployed_addresses_output = vm.serializeAddress( + deployed_addresses, + "operatorStateRetriever", + address(operatorStateRetriever) + ); + + // serialize all the data + string memory finalJson = vm.serializeString( + parent_object, + deployed_addresses, + deployed_addresses_output + ); + + writeOutput(finalJson, "credible_squaring_avs_deployment_output"); + } +} diff --git a/temp-incredible-squaring-avs/contracts/script/output/31337/credible_squaring_avs_deployment_output.json b/temp-incredible-squaring-avs/contracts/script/output/31337/credible_squaring_avs_deployment_output.json new file mode 100644 index 0000000..1b14764 --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/script/output/31337/credible_squaring_avs_deployment_output.json @@ -0,0 +1,13 @@ +{ + "addresses": { + "credibleSquaringServiceManager": "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB", + "credibleSquaringServiceManagerImplementation": "0x36C02dA8a0983159322a80FFE9F24b1acfF8B570", + "credibleSquaringTaskManager": "0x9E545E3C0baAB3E08CdfD552C960A1050f373042", + "credibleSquaringTaskManagerImplementation": "0x4c5859f0F772848b2D91F1D83E2Fe57935348029", + "erc20Mock": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F", + "erc20MockStrategy": "0x09635F643e140090A9A8Dcd712eD6285858ceBef", + "operatorStateRetriever": "0x95401dc811bb5740090279Ba06cfA8fcF6113778", + "registryCoordinator": "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9", + "registryCoordinatorImplementation": "0x9d4454B023096f34B160D6B654540c56A1F81688" + } +} \ No newline at end of file diff --git a/temp-incredible-squaring-avs/contracts/script/output/31337/eigenlayer_deployment_output.json b/temp-incredible-squaring-avs/contracts/script/output/31337/eigenlayer_deployment_output.json new file mode 100644 index 0000000..eaaaa2a --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/script/output/31337/eigenlayer_deployment_output.json @@ -0,0 +1,31 @@ +{ + "addresses": { + "avsDirectory": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707", + "avsDirectoryImplementation": "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82", + "baseStrategyImplementation": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44", + "delayedWithdrawalRouter": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6", + "delayedWithdrawalRouterImplementation": "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1", + "delegation": "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", + "delegationImplementation": "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e", + "eigenLayerPauserReg": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + "eigenLayerProxyAdmin": "0x5FbDB2315678afecb367f032d93F642f64180aa3", + "eigenPodBeacon": "0x610178dA211FEF7D417bC0e6FeD39F05609AD788", + "eigenPodImplementation": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + "eigenPodManager": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853", + "eigenPodManagerImplementation": "0x0B306BF915C4d645ff596e518fAf3F9669b97016", + "emptyContract": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", + "slasher": "0x0165878A594ca255338adfa4d48449f69242Eb8F", + "slasherImplementation": "0x9A676e781A523b5d0C0e43731313A708CB607508", + "strategies": "", + "strategyManager": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + "strategyManagerImplementation": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0" + }, + "chainInfo": { + "chainId": 31337, + "deploymentBlock": 0 + }, + "parameters": { + "executorMultisig": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "operationsMultisig": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + } +} \ No newline at end of file diff --git a/temp-incredible-squaring-avs/contracts/script/utils/Utils.sol b/temp-incredible-squaring-avs/contracts/script/utils/Utils.sol new file mode 100644 index 0000000..9310c76 --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/script/utils/Utils.sol @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity =0.8.12; + +import "@eigenlayer-middleware/src/interfaces/IRegistryCoordinator.sol"; +import "@eigenlayer/contracts/strategies/StrategyBase.sol"; +import "../../src/ERC20Mock.sol"; + +import "forge-std/Script.sol"; +import "forge-std/StdJson.sol"; + +contract Utils is Script { + // Note that this fct will only work for the ERC20Mock that has a public mint function + function _mintTokens( + address strategyAddress, + address[] memory tos, + uint256[] memory amounts + ) internal { + for (uint256 i = 0; i < tos.length; i++) { + ERC20Mock underlyingToken = ERC20Mock( + address(StrategyBase(strategyAddress).underlyingToken()) + ); + underlyingToken.mint(tos[i], amounts[i]); + } + } + + function convertBoolToString( + bool input + ) public pure returns (string memory) { + if (input) { + return "true"; + } else { + return "false"; + } + } + + function convertOperatorStatusToString( + IRegistryCoordinator.OperatorStatus operatorStatus + ) public pure returns (string memory) { + if ( + operatorStatus == + IRegistryCoordinator.OperatorStatus.NEVER_REGISTERED + ) { + return "NEVER_REGISTERED"; + } else if ( + operatorStatus == IRegistryCoordinator.OperatorStatus.REGISTERED + ) { + return "REGISTERED"; + } else if ( + operatorStatus == IRegistryCoordinator.OperatorStatus.DEREGISTERED + ) { + return "DEREGISTERED"; + } else { + return "UNKNOWN"; + } + } + + // Forge scripts best practice: https://book.getfoundry.sh/tutorials/best-practices#scripts + function readInput( + string memory inputFileName + ) internal view returns (string memory) { + string memory inputDir = string.concat( + vm.projectRoot(), + "/script/input/" + ); + string memory chainDir = string.concat(vm.toString(block.chainid), "/"); + string memory file = string.concat(inputFileName, ".json"); + return vm.readFile(string.concat(inputDir, chainDir, file)); + } + + function readOutput( + string memory outputFileName + ) internal view returns (string memory) { + string memory inputDir = string.concat( + vm.projectRoot(), + "/script/output/" + ); + string memory chainDir = string.concat(vm.toString(block.chainid), "/"); + string memory file = string.concat(outputFileName, ".json"); + return vm.readFile(string.concat(inputDir, chainDir, file)); + } + + function writeOutput( + string memory outputJson, + string memory outputFileName + ) internal { + string memory outputDir = string.concat( + vm.projectRoot(), + "/script/output/" + ); + string memory chainDir = string.concat(vm.toString(block.chainid), "/"); + string memory outputFilePath = string.concat( + outputDir, + chainDir, + outputFileName, + ".json" + ); + vm.writeJson(outputJson, outputFilePath); + } +} diff --git a/temp-incredible-squaring-avs/contracts/src/ERC20Mock.sol b/temp-incredible-squaring-avs/contracts/src/ERC20Mock.sol new file mode 100644 index 0000000..de379fc --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/src/ERC20Mock.sol @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) + +pragma solidity =0.8.12; + +import "@openzeppelin/contracts/interfaces/IERC20.sol"; +import "@openzeppelin/contracts/utils/Context.sol"; + +/** + * @dev Implementation of the {IERC20} interface. + * + * This implementation is agnostic to the way tokens are created. This means + * that a supply mechanism has to be added in a derived contract using {_mint}. + * For a generic mechanism see {ERC20PresetMinterPauser}. + * + * TIP: For a detailed writeup see our guide + * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How + * to implement supply mechanisms]. + * + * The default value of {decimals} is 18. To change this, you should override + * this function so it returns a different value. + * + * We have followed general OpenZeppelin Contracts guidelines: functions revert + * instead returning `false` on failure. This behavior is nonetheless + * conventional and does not conflict with the expectations of ERC20 + * applications. + * + * Additionally, an {Approval} event is emitted on calls to {transferFrom}. + * This allows applications to reconstruct the allowance for all accounts just + * by listening to said events. Other implementations of the EIP may not emit + * these events, as it isn't required by the specification. + * + * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} + * functions have been added to mitigate the well-known issues around setting + * allowances. See {IERC20-approve}. + */ +contract ERC20Mock is Context, IERC20 { + mapping(address => uint256) private _balances; + + mapping(address => mapping(address => uint256)) private _allowances; + + uint256 private _totalSupply; + + /** + * @dev See {IERC20-totalSupply}. + */ + function totalSupply() public view virtual override returns (uint256) { + return _totalSupply; + } + + /** + * @dev See {IERC20-balanceOf}. + */ + function balanceOf( + address account + ) public view virtual override returns (uint256) { + return _balances[account]; + } + + function mint(address account, uint256 amount) public { + _mint(account, amount); + } + + /** + * @dev See {IERC20-transfer}. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - the caller must have a balance of at least `amount`. + */ + function transfer( + address to, + uint256 amount + ) public virtual override returns (bool) { + address owner = _msgSender(); + _transfer(owner, to, amount); + return true; + } + + /** + * @dev See {IERC20-allowance}. + */ + function allowance( + address owner, + address spender + ) public view virtual override returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev See {IERC20-approve}. + * + * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on + * `transferFrom`. This is semantically equivalent to an infinite approval. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve( + address /*spender*/, + uint256 /*amount*/ + ) public virtual override returns (bool) { + return true; + } + + /** + * @dev See {IERC20-transferFrom}. + * + * Emits an {Approval} event indicating the updated allowance. This is not + * required by the EIP. See the note at the beginning of {ERC20}. + * + * NOTE: Does not update the allowance if the current allowance + * is the maximum `uint256`. + * + * Requirements: + * + * - `from` and `to` cannot be the zero address. + * - `from` must have a balance of at least `amount`. + * - the caller must have allowance for ``from``'s tokens of at least + * `amount`. + */ + function transferFrom( + address from, + address to, + uint256 amount + ) public virtual override returns (bool) { + _transfer(from, to, amount); + return true; + } + + /** + * @dev Moves `amount` of tokens from `from` to `to`. + * + * This internal function is equivalent to {transfer}, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a {Transfer} event. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `from` must have a balance of at least `amount`. + */ + function _transfer( + address from, + address to, + uint256 amount + ) internal virtual { + require(from != address(0), "ERC20: transfer from the zero address"); + require(to != address(0), "ERC20: transfer to the zero address"); + + _beforeTokenTransfer(from, to, amount); + + require( + _balances[from] >= amount, + "ERC20: transfer amount exceeds balance" + ); + unchecked { + _balances[from] = _balances[from] - amount; + // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by + // decrementing then incrementing. + _balances[to] += amount; + } + + emit Transfer(from, to, amount); + + _afterTokenTransfer(from, to, amount); + } + + /** @dev Creates `amount` tokens and assigns them to `account`, increasing + * the total supply. + * + * Emits a {Transfer} event with `from` set to the zero address. + * + * Requirements: + * + * - `account` cannot be the zero address. + */ + function _mint(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: mint to the zero address"); + + _totalSupply += amount; + unchecked { + // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. + _balances[account] += amount; + } + emit Transfer(address(0), account, amount); + } + + /** + * @dev Destroys `amount` tokens from `account`, reducing the + * total supply. + * + * Emits a {Transfer} event with `to` set to the zero address. + * + * Requirements: + * + * - `account` cannot be the zero address. + * - `account` must have at least `amount` tokens. + */ + function _burn(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: burn from the zero address"); + + _beforeTokenTransfer(account, address(0), amount); + + uint256 accountBalance = _balances[account]; + require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); + unchecked { + _balances[account] = accountBalance - amount; + // Overflow not possible: amount <= accountBalance <= totalSupply. + _totalSupply -= amount; + } + + emit Transfer(account, address(0), amount); + + _afterTokenTransfer(account, address(0), amount); + } + + /** + * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. + * + * This internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + */ + function _approve( + address owner, + address spender, + uint256 amount + ) internal virtual { + require(owner != address(0), "ERC20: approve from the zero address"); + require(spender != address(0), "ERC20: approve to the zero address"); + + _allowances[owner][spender] = amount; + emit Approval(owner, spender, amount); + } + + /** + * @dev Updates `owner` s allowance for `spender` based on spent `amount`. + * + * Does not update the allowance amount in case of infinite allowance. + * Revert if not enough allowance is available. + * + * Might emit an {Approval} event. + */ + function _spendAllowance( + address owner, + address spender, + uint256 amount + ) internal virtual { + uint256 currentAllowance = allowance(owner, spender); + if (currentAllowance != type(uint256).max) { + require( + currentAllowance >= amount, + "ERC20: insufficient allowance" + ); + } + } + + /** + * @dev Hook that is called before any transfer of tokens. This includes + * minting and burning. + * + * Calling conditions: + * + * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens + * will be transferred to `to`. + * - when `from` is zero, `amount` tokens will be minted for `to`. + * - when `to` is zero, `amount` of ``from``'s tokens will be burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _beforeTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual {} + + /** + * @dev Hook that is called after any transfer of tokens. This includes + * minting and burning. + * + * Calling conditions: + * + * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens + * has been transferred to `to`. + * - when `from` is zero, `amount` tokens have been minted for `to`. + * - when `to` is zero, `amount` of ``from``'s tokens have been burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _afterTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual {} +} diff --git a/temp-incredible-squaring-avs/contracts/src/IIncredibleSquaringTaskManager.sol b/temp-incredible-squaring-avs/contracts/src/IIncredibleSquaringTaskManager.sol new file mode 100644 index 0000000..6e6fcfc --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/src/IIncredibleSquaringTaskManager.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.9; + +import "@eigenlayer-middleware/src/libraries/BN254.sol"; + +interface IIncredibleSquaringTaskManager { + // EVENTS + event NewTaskCreated(uint32 indexed taskIndex, Task task); + + event TaskResponded( + TaskResponse taskResponse, + TaskResponseMetadata taskResponseMetadata + ); + + event TaskCompleted(uint32 indexed taskIndex); + + event TaskChallengedSuccessfully( + uint32 indexed taskIndex, + address indexed challenger + ); + + event TaskChallengedUnsuccessfully( + uint32 indexed taskIndex, + address indexed challenger + ); + + // STRUCTS + struct Task { + uint256 numberToBeSquared; + uint32 taskCreatedBlock; + // task submitter decides on the criteria for a task to be completed + // note that this does not mean the task was "correctly" answered (i.e. the number was squared correctly) + // this is for the challenge logic to verify + // task is completed (and contract will accept its TaskResponse) when each quorumNumbers specified here + // are signed by at least quorumThresholdPercentage of the operators + // note that we set the quorumThresholdPercentage to be the same for all quorumNumbers, but this could be changed + bytes quorumNumbers; + uint32 quorumThresholdPercentage; + } + + // Task response is hashed and signed by operators. + // these signatures are aggregated and sent to the contract as response. + struct TaskResponse { + // Can be obtained by the operator from the event NewTaskCreated. + uint32 referenceTaskIndex; + // This is just the response that the operator has to compute by itself. + uint256 numberSquared; + } + + // Extra information related to taskResponse, which is filled inside the contract. + // It thus cannot be signed by operators, so we keep it in a separate struct than TaskResponse + // This metadata is needed by the challenger, so we emit it in the TaskResponded event + struct TaskResponseMetadata { + uint32 taskResponsedBlock; + bytes32 hashOfNonSigners; + } + + // FUNCTIONS + // NOTE: this function creates new task. + function createNewTask( + uint256 numberToBeSquared, + uint32 quorumThresholdPercentage, + bytes calldata quorumNumbers + ) external; + + /// @notice Returns the current 'taskNumber' for the middleware + function taskNumber() external view returns (uint32); + + // // NOTE: this function raises challenge to existing tasks. + function raiseAndResolveChallenge( + Task calldata task, + TaskResponse calldata taskResponse, + TaskResponseMetadata calldata taskResponseMetadata, + BN254.G1Point[] memory pubkeysOfNonSigningOperators + ) external; + + /// @notice Returns the TASK_RESPONSE_WINDOW_BLOCK + function getTaskResponseWindowBlock() external view returns (uint32); +} diff --git a/temp-incredible-squaring-avs/contracts/src/IncredibleSquaringServiceManager.sol b/temp-incredible-squaring-avs/contracts/src/IncredibleSquaringServiceManager.sol new file mode 100644 index 0000000..aaf2bfe --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/src/IncredibleSquaringServiceManager.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.9; + +import "@eigenlayer/contracts/libraries/BytesLib.sol"; +import "./IIncredibleSquaringTaskManager.sol"; +import "@eigenlayer-middleware/src/ServiceManagerBase.sol"; + +/** + * @title Primary entrypoint for procuring services from IncredibleSquaring. + * @author Layr Labs, Inc. + */ +contract IncredibleSquaringServiceManager is ServiceManagerBase { + using BytesLib for bytes; + + IIncredibleSquaringTaskManager + public immutable incredibleSquaringTaskManager; + + /// @notice when applied to a function, ensures that the function is only callable by the `registryCoordinator`. + modifier onlyIncredibleSquaringTaskManager() { + require( + msg.sender == address(incredibleSquaringTaskManager), + "onlyIncredibleSquaringTaskManager: not from credible squaring task manager" + ); + _; + } + + constructor( + IAVSDirectory _avsDirectory, + IRegistryCoordinator _registryCoordinator, + IStakeRegistry _stakeRegistry, + IIncredibleSquaringTaskManager _incredibleSquaringTaskManager + ) + ServiceManagerBase( + _avsDirectory, + IPaymentCoordinator(address(0)), // inc-sq doesn't need to deal with payments + _registryCoordinator, + _stakeRegistry + ) + { + incredibleSquaringTaskManager = _incredibleSquaringTaskManager; + } + + /// @notice Called in the event of challenge resolution, in order to forward a call to the Slasher, which 'freezes' the `operator`. + /// @dev The Slasher contract is under active development and its interface expected to change. + /// We recommend writing slashing logic without integrating with the Slasher at this point in time. + function freezeOperator( + address operatorAddr + ) external onlyIncredibleSquaringTaskManager { + // slasher.freezeOperator(operatorAddr); + } +} diff --git a/temp-incredible-squaring-avs/contracts/src/IncredibleSquaringTaskManager.sol b/temp-incredible-squaring-avs/contracts/src/IncredibleSquaringTaskManager.sol new file mode 100644 index 0000000..d1762cf --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/src/IncredibleSquaringTaskManager.sol @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.9; + +import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; +import "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; +import "@eigenlayer/contracts/permissions/Pausable.sol"; +import "@eigenlayer-middleware/src/interfaces/IServiceManager.sol"; +import {BLSApkRegistry} from "@eigenlayer-middleware/src/BLSApkRegistry.sol"; +import {RegistryCoordinator} from "@eigenlayer-middleware/src/RegistryCoordinator.sol"; +import {BLSSignatureChecker, IRegistryCoordinator} from "@eigenlayer-middleware/src/BLSSignatureChecker.sol"; +import {OperatorStateRetriever} from "@eigenlayer-middleware/src/OperatorStateRetriever.sol"; +import "@eigenlayer-middleware/src/libraries/BN254.sol"; +import "./IIncredibleSquaringTaskManager.sol"; + +contract IncredibleSquaringTaskManager is + Initializable, + OwnableUpgradeable, + Pausable, + BLSSignatureChecker, + OperatorStateRetriever, + IIncredibleSquaringTaskManager +{ + using BN254 for BN254.G1Point; + + /* CONSTANT */ + // The number of blocks from the task initialization within which the aggregator has to respond to + uint32 public immutable TASK_RESPONSE_WINDOW_BLOCK; + uint32 public constant TASK_CHALLENGE_WINDOW_BLOCK = 100; + uint256 internal constant _THRESHOLD_DENOMINATOR = 100; + + /* STORAGE */ + // The latest task index + uint32 public latestTaskNum; + + // mapping of task indices to all tasks hashes + // when a task is created, task hash is stored here, + // and responses need to pass the actual task, + // which is hashed onchain and checked against this mapping + mapping(uint32 => bytes32) public allTaskHashes; + + // mapping of task indices to hash of abi.encode(taskResponse, taskResponseMetadata) + mapping(uint32 => bytes32) public allTaskResponses; + + mapping(uint32 => bool) public taskSuccesfullyChallenged; + + address public aggregator; + address public generator; + + /* MODIFIERS */ + modifier onlyAggregator() { + require(msg.sender == aggregator, "Aggregator must be the caller"); + _; + } + + // onlyTaskGenerator is used to restrict createNewTask from only being called by a permissioned entity + // in a real world scenario, this would be removed by instead making createNewTask a payable function + modifier onlyTaskGenerator() { + require(msg.sender == generator, "Task generator must be the caller"); + _; + } + + constructor( + IRegistryCoordinator _registryCoordinator, + uint32 _taskResponseWindowBlock + ) BLSSignatureChecker(_registryCoordinator) { + TASK_RESPONSE_WINDOW_BLOCK = _taskResponseWindowBlock; + } + + function initialize( + IPauserRegistry _pauserRegistry, + address initialOwner, + address _aggregator, + address _generator + ) public initializer { + _initializePauser(_pauserRegistry, UNPAUSE_ALL); + _transferOwnership(initialOwner); + aggregator = _aggregator; + generator = _generator; + } + + /* FUNCTIONS */ + // NOTE: this function creates new task, assigns it a taskId + function createNewTask( + uint256 numberToBeSquared, + uint32 quorumThresholdPercentage, + bytes calldata quorumNumbers + ) external onlyTaskGenerator { + // create a new task struct + Task memory newTask; + newTask.numberToBeSquared = numberToBeSquared; + newTask.taskCreatedBlock = uint32(block.number); + newTask.quorumThresholdPercentage = quorumThresholdPercentage; + newTask.quorumNumbers = quorumNumbers; + + // store hash of task onchain, emit event, and increase taskNum + allTaskHashes[latestTaskNum] = keccak256(abi.encode(newTask)); + emit NewTaskCreated(latestTaskNum, newTask); + latestTaskNum = latestTaskNum + 1; + } + + // NOTE: this function responds to existing tasks. + function respondToTask( + Task calldata task, + TaskResponse calldata taskResponse, + NonSignerStakesAndSignature memory nonSignerStakesAndSignature + ) external onlyAggregator { + uint32 taskCreatedBlock = task.taskCreatedBlock; + bytes calldata quorumNumbers = task.quorumNumbers; + uint32 quorumThresholdPercentage = task.quorumThresholdPercentage; + + // check that the task is valid, hasn't been responsed yet, and is being responsed in time + require( + keccak256(abi.encode(task)) == + allTaskHashes[taskResponse.referenceTaskIndex], + "supplied task does not match the one recorded in the contract" + ); + // some logical checks + require( + allTaskResponses[taskResponse.referenceTaskIndex] == bytes32(0), + "Aggregator has already responded to the task" + ); + require( + uint32(block.number) <= + taskCreatedBlock + TASK_RESPONSE_WINDOW_BLOCK, + "Aggregator has responded to the task too late" + ); + + /* CHECKING SIGNATURES & WHETHER THRESHOLD IS MET OR NOT */ + // calculate message which operators signed + bytes32 message = keccak256(abi.encode(taskResponse)); + + // check the BLS signature + ( + QuorumStakeTotals memory quorumStakeTotals, + bytes32 hashOfNonSigners + ) = checkSignatures( + message, + quorumNumbers, + taskCreatedBlock, + nonSignerStakesAndSignature + ); + + // check that signatories own at least a threshold percentage of each quourm + for (uint i = 0; i < quorumNumbers.length; i++) { + // we don't check that the quorumThresholdPercentages are not >100 because a greater value would trivially fail the check, implying + // signed stake > total stake + require( + quorumStakeTotals.signedStakeForQuorum[i] * + _THRESHOLD_DENOMINATOR >= + quorumStakeTotals.totalStakeForQuorum[i] * + uint8(quorumThresholdPercentage), + "Signatories do not own at least threshold percentage of a quorum" + ); + } + + TaskResponseMetadata memory taskResponseMetadata = TaskResponseMetadata( + uint32(block.number), + hashOfNonSigners + ); + // updating the storage with task responsea + allTaskResponses[taskResponse.referenceTaskIndex] = keccak256( + abi.encode(taskResponse, taskResponseMetadata) + ); + + // emitting event + emit TaskResponded(taskResponse, taskResponseMetadata); + } + + function taskNumber() external view returns (uint32) { + return latestTaskNum; + } + + // NOTE: this function enables a challenger to raise and resolve a challenge. + // TODO: require challenger to pay a bond for raising a challenge + // TODO(samlaf): should we check that quorumNumbers is same as the one recorded in the task? + function raiseAndResolveChallenge( + Task calldata task, + TaskResponse calldata taskResponse, + TaskResponseMetadata calldata taskResponseMetadata, + BN254.G1Point[] memory pubkeysOfNonSigningOperators + ) external { + uint32 referenceTaskIndex = taskResponse.referenceTaskIndex; + uint256 numberToBeSquared = task.numberToBeSquared; + // some logical checks + require( + allTaskResponses[referenceTaskIndex] != bytes32(0), + "Task hasn't been responded to yet" + ); + require( + allTaskResponses[referenceTaskIndex] == + keccak256(abi.encode(taskResponse, taskResponseMetadata)), + "Task response does not match the one recorded in the contract" + ); + require( + taskSuccesfullyChallenged[referenceTaskIndex] == false, + "The response to this task has already been challenged successfully." + ); + + require( + uint32(block.number) <= + taskResponseMetadata.taskResponsedBlock + + TASK_CHALLENGE_WINDOW_BLOCK, + "The challenge period for this task has already expired." + ); + + // logic for checking whether challenge is valid or not + uint256 actualSquaredOutput = numberToBeSquared * numberToBeSquared; + bool isResponseCorrect = (actualSquaredOutput == + taskResponse.numberSquared); + + // if response was correct, no slashing happens so we return + if (isResponseCorrect == true) { + emit TaskChallengedUnsuccessfully(referenceTaskIndex, msg.sender); + return; + } + + // get the list of hash of pubkeys of operators who weren't part of the task response submitted by the aggregator + bytes32[] memory hashesOfPubkeysOfNonSigningOperators = new bytes32[]( + pubkeysOfNonSigningOperators.length + ); + for (uint i = 0; i < pubkeysOfNonSigningOperators.length; i++) { + hashesOfPubkeysOfNonSigningOperators[ + i + ] = pubkeysOfNonSigningOperators[i].hashG1Point(); + } + + // verify whether the pubkeys of "claimed" non-signers supplied by challenger are actually non-signers as recorded before + // when the aggregator responded to the task + // currently inlined, as the MiddlewareUtils.computeSignatoryRecordHash function was removed from BLSSignatureChecker + // in this PR: https://github.com/Layr-Labs/eigenlayer-contracts/commit/c836178bf57adaedff37262dff1def18310f3dce#diff-8ab29af002b60fc80e3d6564e37419017c804ae4e788f4c5ff468ce2249b4386L155-L158 + // TODO(samlaf): contracts team will add this function back in the BLSSignatureChecker, which we should use to prevent potential bugs from code duplication + bytes32 signatoryRecordHash = keccak256( + abi.encodePacked( + task.taskCreatedBlock, + hashesOfPubkeysOfNonSigningOperators + ) + ); + require( + signatoryRecordHash == taskResponseMetadata.hashOfNonSigners, + "The pubkeys of non-signing operators supplied by the challenger are not correct." + ); + + // get the address of operators who didn't sign + address[] memory addresssOfNonSigningOperators = new address[]( + pubkeysOfNonSigningOperators.length + ); + for (uint i = 0; i < pubkeysOfNonSigningOperators.length; i++) { + addresssOfNonSigningOperators[i] = BLSApkRegistry( + address(blsApkRegistry) + ).pubkeyHashToOperator(hashesOfPubkeysOfNonSigningOperators[i]); + } + + // @dev the below code is commented out for the upcoming M2 release + // in which there will be no slashing. The slasher is also being redesigned + // so its interface may very well change. + // ========================================== + // // get the list of all operators who were active when the task was initialized + // Operator[][] memory allOperatorInfo = getOperatorState( + // IRegistryCoordinator(address(registryCoordinator)), + // task.quorumNumbers, + // task.taskCreatedBlock + // ); + // // freeze the operators who signed adversarially + // for (uint i = 0; i < allOperatorInfo.length; i++) { + // // first for loop iterate over quorums + + // for (uint j = 0; j < allOperatorInfo[i].length; j++) { + // // second for loop iterate over operators active in the quorum when the task was initialized + + // // get the operator address + // bytes32 operatorID = allOperatorInfo[i][j].operatorId; + // address operatorAddress = BLSPubkeyRegistry( + // address(blsPubkeyRegistry) + // ).pubkeyCompendium().pubkeyHashToOperator(operatorID); + + // // check if the operator has already NOT been frozen + // if ( + // IServiceManager( + // address( + // BLSRegistryCoordinatorWithIndices( + // address(registryCoordinator) + // ).serviceManager() + // ) + // ).slasher().isFrozen(operatorAddress) == false + // ) { + // // check whether the operator was a signer for the task + // bool wasSigningOperator = true; + // for ( + // uint k = 0; + // k < addresssOfNonSigningOperators.length; + // k++ + // ) { + // if ( + // operatorAddress == addresssOfNonSigningOperators[k] + // ) { + // // if the operator was a non-signer, then we set the flag to false + // wasSigningOperator == false; + // break; + // } + // } + + // if (wasSigningOperator == true) { + // BLSRegistryCoordinatorWithIndices( + // address(registryCoordinator) + // ).serviceManager().freezeOperator(operatorAddress); + // } + // } + // } + // } + + // the task response has been challenged successfully + taskSuccesfullyChallenged[referenceTaskIndex] = true; + + emit TaskChallengedSuccessfully(referenceTaskIndex, msg.sender); + } + + function getTaskResponseWindowBlock() external view returns (uint32) { + return TASK_RESPONSE_WINDOW_BLOCK; + } +} diff --git a/temp-incredible-squaring-avs/contracts/test/CredibleSquaringTaskManager.t.sol b/temp-incredible-squaring-avs/contracts/test/CredibleSquaringTaskManager.t.sol new file mode 100644 index 0000000..2022adf --- /dev/null +++ b/temp-incredible-squaring-avs/contracts/test/CredibleSquaringTaskManager.t.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.12; + +import "../src/IncredibleSquaringServiceManager.sol" as incsqsm; +import {IncredibleSquaringTaskManager} from "../src/IncredibleSquaringTaskManager.sol"; +import {BLSMockAVSDeployer} from "@eigenlayer-middleware/test/utils/BLSMockAVSDeployer.sol"; +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; + +contract IncredibleSquaringTaskManagerTest is BLSMockAVSDeployer { + incsqsm.IncredibleSquaringServiceManager sm; + incsqsm.IncredibleSquaringServiceManager smImplementation; + IncredibleSquaringTaskManager tm; + IncredibleSquaringTaskManager tmImplementation; + + uint32 public constant TASK_RESPONSE_WINDOW_BLOCK = 30; + address aggregator = + address(uint160(uint256(keccak256(abi.encodePacked("aggregator"))))); + address generator = + address(uint160(uint256(keccak256(abi.encodePacked("generator"))))); + + function setUp() public { + _setUpBLSMockAVSDeployer(); + + tmImplementation = new IncredibleSquaringTaskManager( + incsqsm.IRegistryCoordinator(address(registryCoordinator)), + TASK_RESPONSE_WINDOW_BLOCK + ); + + // Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them. + tm = IncredibleSquaringTaskManager( + address( + new TransparentUpgradeableProxy( + address(tmImplementation), + address(proxyAdmin), + abi.encodeWithSelector( + tm.initialize.selector, + pauserRegistry, + registryCoordinatorOwner, + aggregator, + generator + ) + ) + ) + ); + } + + function testCreateNewTask() public { + bytes memory quorumNumbers = new bytes(0); + cheats.prank(generator, generator); + tm.createNewTask(2, 100, quorumNumbers); + assertEq(tm.latestTaskNum(), 1); + } +} diff --git a/temp-incredible-squaring-avs/core/chainio/avs_reader.go b/temp-incredible-squaring-avs/core/chainio/avs_reader.go new file mode 100644 index 0000000..55bcc48 --- /dev/null +++ b/temp-incredible-squaring-avs/core/chainio/avs_reader.go @@ -0,0 +1,76 @@ +package chainio + +import ( + "context" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + gethcommon "github.com/ethereum/go-ethereum/common" + + sdkavsregistry "github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry" + "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" + logging "github.com/Layr-Labs/eigensdk-go/logging" + + erc20mock "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/ERC20Mock" + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" +) + +type AvsReaderer interface { + sdkavsregistry.AvsRegistryReader + + CheckSignatures( + ctx context.Context, msgHash [32]byte, quorumNumbers []byte, referenceBlockNumber uint32, nonSignerStakesAndSignature cstaskmanager.IBLSSignatureCheckerNonSignerStakesAndSignature, + ) (cstaskmanager.IBLSSignatureCheckerQuorumStakeTotals, error) + GetErc20Mock(ctx context.Context, tokenAddr gethcommon.Address) (*erc20mock.ContractERC20Mock, error) +} + +type AvsReader struct { + sdkavsregistry.AvsRegistryReader + AvsServiceBindings *AvsManagersBindings + logger logging.Logger +} + +var _ AvsReaderer = (*AvsReader)(nil) + +func BuildAvsReaderFromConfig(c *config.Config) (*AvsReader, error) { + return BuildAvsReader(c.IncredibleSquaringRegistryCoordinatorAddr, c.OperatorStateRetrieverAddr, c.EthHttpClient, c.Logger) +} +func BuildAvsReader(registryCoordinatorAddr, operatorStateRetrieverAddr gethcommon.Address, ethHttpClient eth.Client, logger logging.Logger) (*AvsReader, error) { + avsManagersBindings, err := NewAvsManagersBindings(registryCoordinatorAddr, operatorStateRetrieverAddr, ethHttpClient, logger) + if err != nil { + return nil, err + } + avsRegistryReader, err := sdkavsregistry.BuildAvsRegistryChainReader(registryCoordinatorAddr, operatorStateRetrieverAddr, ethHttpClient, logger) + if err != nil { + return nil, err + } + return NewAvsReader(avsRegistryReader, avsManagersBindings, logger) +} +func NewAvsReader(avsRegistryReader sdkavsregistry.AvsRegistryReader, avsServiceBindings *AvsManagersBindings, logger logging.Logger) (*AvsReader, error) { + return &AvsReader{ + AvsRegistryReader: avsRegistryReader, + AvsServiceBindings: avsServiceBindings, + logger: logger, + }, nil +} + +func (r *AvsReader) CheckSignatures( + ctx context.Context, msgHash [32]byte, quorumNumbers []byte, referenceBlockNumber uint32, nonSignerStakesAndSignature cstaskmanager.IBLSSignatureCheckerNonSignerStakesAndSignature, +) (cstaskmanager.IBLSSignatureCheckerQuorumStakeTotals, error) { + stakeTotalsPerQuorum, _, err := r.AvsServiceBindings.TaskManager.CheckSignatures( + &bind.CallOpts{}, msgHash, quorumNumbers, referenceBlockNumber, nonSignerStakesAndSignature, + ) + if err != nil { + return cstaskmanager.IBLSSignatureCheckerQuorumStakeTotals{}, err + } + return stakeTotalsPerQuorum, nil +} + +func (r *AvsReader) GetErc20Mock(ctx context.Context, tokenAddr gethcommon.Address) (*erc20mock.ContractERC20Mock, error) { + erc20Mock, err := r.AvsServiceBindings.GetErc20Mock(tokenAddr) + if err != nil { + r.logger.Error("Failed to fetch ERC20Mock contract", "err", err) + return nil, err + } + return erc20Mock, nil +} diff --git a/temp-incredible-squaring-avs/core/chainio/avs_subscriber.go b/temp-incredible-squaring-avs/core/chainio/avs_subscriber.go new file mode 100644 index 0000000..fcf7db1 --- /dev/null +++ b/temp-incredible-squaring-avs/core/chainio/avs_subscriber.go @@ -0,0 +1,80 @@ +package chainio + +import ( + "github.com/ethereum/go-ethereum/accounts/abi/bind" + gethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + + "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" + sdklogging "github.com/Layr-Labs/eigensdk-go/logging" + + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" +) + +type AvsSubscriberer interface { + SubscribeToNewTasks(newTaskCreatedChan chan *cstaskmanager.ContractIncredibleSquaringTaskManagerNewTaskCreated) event.Subscription + SubscribeToTaskResponses(taskResponseLogs chan *cstaskmanager.ContractIncredibleSquaringTaskManagerTaskResponded) event.Subscription + ParseTaskResponded(rawLog types.Log) (*cstaskmanager.ContractIncredibleSquaringTaskManagerTaskResponded, error) +} + +// Subscribers use a ws connection instead of http connection like Readers +// kind of stupid that the geth client doesn't have a unified interface for both... +// it takes a single url, so the bindings, even though they have watcher functions, those can't be used +// with the http connection... seems very very stupid. Am I missing something? +type AvsSubscriber struct { + AvsContractBindings *AvsManagersBindings + logger sdklogging.Logger +} + +func BuildAvsSubscriberFromConfig(config *config.Config) (*AvsSubscriber, error) { + return BuildAvsSubscriber( + config.IncredibleSquaringRegistryCoordinatorAddr, + config.OperatorStateRetrieverAddr, + config.EthWsClient, + config.Logger, + ) +} + +func BuildAvsSubscriber(registryCoordinatorAddr, blsOperatorStateRetrieverAddr gethcommon.Address, ethclient eth.Client, logger sdklogging.Logger) (*AvsSubscriber, error) { + avsContractBindings, err := NewAvsManagersBindings(registryCoordinatorAddr, blsOperatorStateRetrieverAddr, ethclient, logger) + if err != nil { + logger.Errorf("Failed to create contract bindings", "err", err) + return nil, err + } + return NewAvsSubscriber(avsContractBindings, logger), nil +} + +func NewAvsSubscriber(avsContractBindings *AvsManagersBindings, logger sdklogging.Logger) *AvsSubscriber { + return &AvsSubscriber{ + AvsContractBindings: avsContractBindings, + logger: logger, + } +} + +func (s *AvsSubscriber) SubscribeToNewTasks(newTaskCreatedChan chan *cstaskmanager.ContractIncredibleSquaringTaskManagerNewTaskCreated) event.Subscription { + sub, err := s.AvsContractBindings.TaskManager.WatchNewTaskCreated( + &bind.WatchOpts{}, newTaskCreatedChan, nil, + ) + if err != nil { + s.logger.Error("Failed to subscribe to new TaskManager tasks", "err", err) + } + s.logger.Infof("Subscribed to new TaskManager tasks") + return sub +} + +func (s *AvsSubscriber) SubscribeToTaskResponses(taskResponseChan chan *cstaskmanager.ContractIncredibleSquaringTaskManagerTaskResponded) event.Subscription { + sub, err := s.AvsContractBindings.TaskManager.WatchTaskResponded( + &bind.WatchOpts{}, taskResponseChan, + ) + if err != nil { + s.logger.Error("Failed to subscribe to TaskResponded events", "err", err) + } + s.logger.Infof("Subscribed to TaskResponded events") + return sub +} + +func (s *AvsSubscriber) ParseTaskResponded(rawLog types.Log) (*cstaskmanager.ContractIncredibleSquaringTaskManagerTaskResponded, error) { + return s.AvsContractBindings.TaskManager.ContractIncredibleSquaringTaskManagerFilterer.ParseTaskResponded(rawLog) +} diff --git a/temp-incredible-squaring-avs/core/chainio/avs_writer.go b/temp-incredible-squaring-avs/core/chainio/avs_writer.go new file mode 100644 index 0000000..1a19f23 --- /dev/null +++ b/temp-incredible-squaring-avs/core/chainio/avs_writer.go @@ -0,0 +1,149 @@ +package chainio + +import ( + "context" + "math/big" + + gethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/Layr-Labs/eigensdk-go/chainio/clients/avsregistry" + "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" + "github.com/Layr-Labs/eigensdk-go/chainio/txmgr" + logging "github.com/Layr-Labs/eigensdk-go/logging" + sdktypes "github.com/Layr-Labs/eigensdk-go/types" + + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" +) + +type AvsWriterer interface { + avsregistry.AvsRegistryWriter + + SendNewTaskNumberToSquare( + ctx context.Context, + numToSquare *big.Int, + quorumThresholdPercentage sdktypes.QuorumThresholdPercentage, + quorumNumbers sdktypes.QuorumNums, + ) (cstaskmanager.IIncredibleSquaringTaskManagerTask, uint32, error) + RaiseChallenge( + ctx context.Context, + task cstaskmanager.IIncredibleSquaringTaskManagerTask, + taskResponse cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse, + taskResponseMetadata cstaskmanager.IIncredibleSquaringTaskManagerTaskResponseMetadata, + pubkeysOfNonSigningOperators []cstaskmanager.BN254G1Point, + ) (*types.Receipt, error) + SendAggregatedResponse(ctx context.Context, + task cstaskmanager.IIncredibleSquaringTaskManagerTask, + taskResponse cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse, + nonSignerStakesAndSignature cstaskmanager.IBLSSignatureCheckerNonSignerStakesAndSignature, + ) (*types.Receipt, error) +} + +type AvsWriter struct { + avsregistry.AvsRegistryWriter + AvsContractBindings *AvsManagersBindings + logger logging.Logger + TxMgr txmgr.TxManager + client eth.Client +} + +var _ AvsWriterer = (*AvsWriter)(nil) + +func BuildAvsWriterFromConfig(c *config.Config) (*AvsWriter, error) { + return BuildAvsWriter(c.TxMgr, c.IncredibleSquaringRegistryCoordinatorAddr, c.OperatorStateRetrieverAddr, c.EthHttpClient, c.Logger) +} + +func BuildAvsWriter(txMgr txmgr.TxManager, registryCoordinatorAddr, operatorStateRetrieverAddr gethcommon.Address, ethHttpClient eth.Client, logger logging.Logger) (*AvsWriter, error) { + avsServiceBindings, err := NewAvsManagersBindings(registryCoordinatorAddr, operatorStateRetrieverAddr, ethHttpClient, logger) + if err != nil { + logger.Error("Failed to create contract bindings", "err", err) + return nil, err + } + avsRegistryWriter, err := avsregistry.BuildAvsRegistryChainWriter(registryCoordinatorAddr, operatorStateRetrieverAddr, logger, ethHttpClient, txMgr) + if err != nil { + return nil, err + } + return NewAvsWriter(avsRegistryWriter, avsServiceBindings, logger, txMgr), nil +} +func NewAvsWriter(avsRegistryWriter avsregistry.AvsRegistryWriter, avsServiceBindings *AvsManagersBindings, logger logging.Logger, txMgr txmgr.TxManager) *AvsWriter { + return &AvsWriter{ + AvsRegistryWriter: avsRegistryWriter, + AvsContractBindings: avsServiceBindings, + logger: logger, + TxMgr: txMgr, + } +} + +// returns the tx receipt, as well as the task index (which it gets from parsing the tx receipt logs) +func (w *AvsWriter) SendNewTaskNumberToSquare(ctx context.Context, numToSquare *big.Int, quorumThresholdPercentage sdktypes.QuorumThresholdPercentage, quorumNumbers sdktypes.QuorumNums) (cstaskmanager.IIncredibleSquaringTaskManagerTask, uint32, error) { + txOpts, err := w.TxMgr.GetNoSendTxOpts() + if err != nil { + w.logger.Errorf("Error getting tx opts") + return cstaskmanager.IIncredibleSquaringTaskManagerTask{}, 0, err + } + tx, err := w.AvsContractBindings.TaskManager.CreateNewTask(txOpts, numToSquare, uint32(quorumThresholdPercentage), quorumNumbers.UnderlyingType()) + if err != nil { + w.logger.Errorf("Error assembling CreateNewTask tx") + return cstaskmanager.IIncredibleSquaringTaskManagerTask{}, 0, err + } + receipt, err := w.TxMgr.Send(ctx, tx) + if err != nil { + w.logger.Errorf("Error submitting CreateNewTask tx") + return cstaskmanager.IIncredibleSquaringTaskManagerTask{}, 0, err + } + newTaskCreatedEvent, err := w.AvsContractBindings.TaskManager.ContractIncredibleSquaringTaskManagerFilterer.ParseNewTaskCreated(*receipt.Logs[0]) + if err != nil { + w.logger.Error("Aggregator failed to parse new task created event", "err", err) + return cstaskmanager.IIncredibleSquaringTaskManagerTask{}, 0, err + } + return newTaskCreatedEvent.Task, newTaskCreatedEvent.TaskIndex, nil +} + +func (w *AvsWriter) SendAggregatedResponse( + ctx context.Context, task cstaskmanager.IIncredibleSquaringTaskManagerTask, + taskResponse cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse, + nonSignerStakesAndSignature cstaskmanager.IBLSSignatureCheckerNonSignerStakesAndSignature, +) (*types.Receipt, error) { + txOpts, err := w.TxMgr.GetNoSendTxOpts() + if err != nil { + w.logger.Errorf("Error getting tx opts") + return nil, err + } + tx, err := w.AvsContractBindings.TaskManager.RespondToTask(txOpts, task, taskResponse, nonSignerStakesAndSignature) + if err != nil { + w.logger.Error("Error submitting SubmitTaskResponse tx while calling respondToTask", "err", err) + return nil, err + } + receipt, err := w.TxMgr.Send(ctx, tx) + if err != nil { + w.logger.Errorf("Error submitting respondToTask tx") + return nil, err + } + return receipt, nil +} + +func (w *AvsWriter) RaiseChallenge( + ctx context.Context, + task cstaskmanager.IIncredibleSquaringTaskManagerTask, + taskResponse cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse, + taskResponseMetadata cstaskmanager.IIncredibleSquaringTaskManagerTaskResponseMetadata, + pubkeysOfNonSigningOperators []cstaskmanager.BN254G1Point, +) (*types.Receipt, error) { + txOpts, err := w.TxMgr.GetNoSendTxOpts() + if err != nil { + w.logger.Errorf("Error getting tx opts") + return nil, err + } + tx, err := w.AvsContractBindings.TaskManager.RaiseAndResolveChallenge(txOpts, task, taskResponse, taskResponseMetadata, pubkeysOfNonSigningOperators) + if err != nil { + w.logger.Errorf("Error assembling RaiseChallenge tx") + return nil, err + } + receipt, err := w.TxMgr.Send(ctx, tx) + if err != nil { + w.logger.Errorf("Error submitting RaiseChallenge tx") + return nil, err + } + return receipt, nil +} diff --git a/temp-incredible-squaring-avs/core/chainio/bindings.go b/temp-incredible-squaring-avs/core/chainio/bindings.go new file mode 100644 index 0000000..c9c53da --- /dev/null +++ b/temp-incredible-squaring-avs/core/chainio/bindings.go @@ -0,0 +1,65 @@ +package chainio + +import ( + "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" + "github.com/Layr-Labs/eigensdk-go/logging" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + gethcommon "github.com/ethereum/go-ethereum/common" + + regcoord "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator" + erc20mock "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/ERC20Mock" + csservicemanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringServiceManager" + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" +) + +type AvsManagersBindings struct { + TaskManager *cstaskmanager.ContractIncredibleSquaringTaskManager + ServiceManager *csservicemanager.ContractIncredibleSquaringServiceManager + ethClient eth.Client + logger logging.Logger +} + +func NewAvsManagersBindings(registryCoordinatorAddr, operatorStateRetrieverAddr gethcommon.Address, ethclient eth.Client, logger logging.Logger) (*AvsManagersBindings, error) { + contractRegistryCoordinator, err := regcoord.NewContractRegistryCoordinator(registryCoordinatorAddr, ethclient) + if err != nil { + return nil, err + } + serviceManagerAddr, err := contractRegistryCoordinator.ServiceManager(&bind.CallOpts{}) + if err != nil { + return nil, err + } + contractServiceManager, err := csservicemanager.NewContractIncredibleSquaringServiceManager(serviceManagerAddr, ethclient) + if err != nil { + logger.Error("Failed to fetch IServiceManager contract", "err", err) + return nil, err + } + + taskManagerAddr, err := contractServiceManager.IncredibleSquaringTaskManager(&bind.CallOpts{}) + if err != nil { + logger.Error("Failed to fetch TaskManager address", "err", err) + return nil, err + } + contractTaskManager, err := cstaskmanager.NewContractIncredibleSquaringTaskManager(taskManagerAddr, ethclient) + if err != nil { + logger.Error("Failed to fetch IIncredibleSquaringTaskManager contract", "err", err) + return nil, err + } + + return &AvsManagersBindings{ + ServiceManager: contractServiceManager, + TaskManager: contractTaskManager, + ethClient: ethclient, + logger: logger, + }, nil +} + +func (b *AvsManagersBindings) GetErc20Mock(tokenAddr common.Address) (*erc20mock.ContractERC20Mock, error) { + contractErc20Mock, err := erc20mock.NewContractERC20Mock(tokenAddr, b.ethClient) + if err != nil { + b.logger.Error("Failed to fetch ERC20Mock contract", "err", err) + return nil, err + } + return contractErc20Mock, nil +} diff --git a/temp-incredible-squaring-avs/core/chainio/gen.go b/temp-incredible-squaring-avs/core/chainio/gen.go new file mode 100644 index 0000000..f306121 --- /dev/null +++ b/temp-incredible-squaring-avs/core/chainio/gen.go @@ -0,0 +1,5 @@ +package chainio + +//go:generate mockgen -destination=./mocks/avs_subscriber.go -package=mocks github.com/Layr-Labs/incredible-squaring-avs/core/chainio AvsSubscriberer +//go:generate mockgen -destination=./mocks/avs_writer.go -package=mocks github.com/Layr-Labs/incredible-squaring-avs/core/chainio AvsWriterer +//go:generate mockgen -destination=./mocks/avs_reader.go -package=mocks github.com/Layr-Labs/incredible-squaring-avs/core/chainio AvsReaderer diff --git a/temp-incredible-squaring-avs/core/chainio/mocks/avs_reader.go b/temp-incredible-squaring-avs/core/chainio/mocks/avs_reader.go new file mode 100644 index 0000000..4a8ebf1 --- /dev/null +++ b/temp-incredible-squaring-avs/core/chainio/mocks/avs_reader.go @@ -0,0 +1,274 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/Layr-Labs/incredible-squaring-avs/core/chainio (interfaces: AvsReaderer) +// +// Generated by this command: +// +// mockgen -destination=./mocks/avs_reader.go -package=mocks github.com/Layr-Labs/incredible-squaring-avs/core/chainio AvsReaderer +// +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + big "math/big" + reflect "reflect" + + contractOperatorStateRetriever "github.com/Layr-Labs/eigensdk-go/contracts/bindings/OperatorStateRetriever" + types "github.com/Layr-Labs/eigensdk-go/types" + contractERC20Mock "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/ERC20Mock" + contractIncredibleSquaringTaskManager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + bind "github.com/ethereum/go-ethereum/accounts/abi/bind" + common "github.com/ethereum/go-ethereum/common" + gomock "go.uber.org/mock/gomock" +) + +// MockAvsReaderer is a mock of AvsReaderer interface. +type MockAvsReaderer struct { + ctrl *gomock.Controller + recorder *MockAvsReadererMockRecorder +} + +// MockAvsReadererMockRecorder is the mock recorder for MockAvsReaderer. +type MockAvsReadererMockRecorder struct { + mock *MockAvsReaderer +} + +// NewMockAvsReaderer creates a new mock instance. +func NewMockAvsReaderer(ctrl *gomock.Controller) *MockAvsReaderer { + mock := &MockAvsReaderer{ctrl: ctrl} + mock.recorder = &MockAvsReadererMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockAvsReaderer) EXPECT() *MockAvsReadererMockRecorder { + return m.recorder +} + +// CheckSignatures mocks base method. +func (m *MockAvsReaderer) CheckSignatures(arg0 context.Context, arg1 [32]byte, arg2 []byte, arg3 uint32, arg4 contractIncredibleSquaringTaskManager.IBLSSignatureCheckerNonSignerStakesAndSignature) (contractIncredibleSquaringTaskManager.IBLSSignatureCheckerQuorumStakeTotals, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CheckSignatures", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(contractIncredibleSquaringTaskManager.IBLSSignatureCheckerQuorumStakeTotals) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CheckSignatures indicates an expected call of CheckSignatures. +func (mr *MockAvsReadererMockRecorder) CheckSignatures(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckSignatures", reflect.TypeOf((*MockAvsReaderer)(nil).CheckSignatures), arg0, arg1, arg2, arg3, arg4) +} + +// GetCheckSignaturesIndices mocks base method. +func (m *MockAvsReaderer) GetCheckSignaturesIndices(arg0 *bind.CallOpts, arg1 uint32, arg2 types.QuorumNums, arg3 []types.Bytes32) (contractOperatorStateRetriever.OperatorStateRetrieverCheckSignaturesIndices, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCheckSignaturesIndices", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(contractOperatorStateRetriever.OperatorStateRetrieverCheckSignaturesIndices) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCheckSignaturesIndices indicates an expected call of GetCheckSignaturesIndices. +func (mr *MockAvsReadererMockRecorder) GetCheckSignaturesIndices(arg0, arg1, arg2, arg3 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCheckSignaturesIndices", reflect.TypeOf((*MockAvsReaderer)(nil).GetCheckSignaturesIndices), arg0, arg1, arg2, arg3) +} + +// GetErc20Mock mocks base method. +func (m *MockAvsReaderer) GetErc20Mock(arg0 context.Context, arg1 common.Address) (*contractERC20Mock.ContractERC20Mock, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetErc20Mock", arg0, arg1) + ret0, _ := ret[0].(*contractERC20Mock.ContractERC20Mock) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetErc20Mock indicates an expected call of GetErc20Mock. +func (mr *MockAvsReadererMockRecorder) GetErc20Mock(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetErc20Mock", reflect.TypeOf((*MockAvsReaderer)(nil).GetErc20Mock), arg0, arg1) +} + +// GetOperatorAddrsInQuorumsAtCurrentBlock mocks base method. +func (m *MockAvsReaderer) GetOperatorAddrsInQuorumsAtCurrentBlock(arg0 *bind.CallOpts, arg1 types.QuorumNums) ([][]common.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOperatorAddrsInQuorumsAtCurrentBlock", arg0, arg1) + ret0, _ := ret[0].([][]common.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetOperatorAddrsInQuorumsAtCurrentBlock indicates an expected call of GetOperatorAddrsInQuorumsAtCurrentBlock. +func (mr *MockAvsReadererMockRecorder) GetOperatorAddrsInQuorumsAtCurrentBlock(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorAddrsInQuorumsAtCurrentBlock", reflect.TypeOf((*MockAvsReaderer)(nil).GetOperatorAddrsInQuorumsAtCurrentBlock), arg0, arg1) +} + +// GetOperatorFromId mocks base method. +func (m *MockAvsReaderer) GetOperatorFromId(arg0 *bind.CallOpts, arg1 types.Bytes32) (common.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOperatorFromId", arg0, arg1) + ret0, _ := ret[0].(common.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetOperatorFromId indicates an expected call of GetOperatorFromId. +func (mr *MockAvsReadererMockRecorder) GetOperatorFromId(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorFromId", reflect.TypeOf((*MockAvsReaderer)(nil).GetOperatorFromId), arg0, arg1) +} + +// GetOperatorId mocks base method. +func (m *MockAvsReaderer) GetOperatorId(arg0 *bind.CallOpts, arg1 common.Address) ([32]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOperatorId", arg0, arg1) + ret0, _ := ret[0].([32]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetOperatorId indicates an expected call of GetOperatorId. +func (mr *MockAvsReadererMockRecorder) GetOperatorId(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorId", reflect.TypeOf((*MockAvsReaderer)(nil).GetOperatorId), arg0, arg1) +} + +// GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock mocks base method. +func (m *MockAvsReaderer) GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock(arg0 *bind.CallOpts, arg1 types.Bytes32) (map[types.QuorumNum]*big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock", arg0, arg1) + ret0, _ := ret[0].(map[types.QuorumNum]*big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock indicates an expected call of GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock. +func (mr *MockAvsReadererMockRecorder) GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock", reflect.TypeOf((*MockAvsReaderer)(nil).GetOperatorStakeInQuorumsOfOperatorAtCurrentBlock), arg0, arg1) +} + +// GetOperatorsStakeInQuorumsAtBlock mocks base method. +func (m *MockAvsReaderer) GetOperatorsStakeInQuorumsAtBlock(arg0 *bind.CallOpts, arg1 types.QuorumNums, arg2 uint32) ([][]contractOperatorStateRetriever.OperatorStateRetrieverOperator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOperatorsStakeInQuorumsAtBlock", arg0, arg1, arg2) + ret0, _ := ret[0].([][]contractOperatorStateRetriever.OperatorStateRetrieverOperator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetOperatorsStakeInQuorumsAtBlock indicates an expected call of GetOperatorsStakeInQuorumsAtBlock. +func (mr *MockAvsReadererMockRecorder) GetOperatorsStakeInQuorumsAtBlock(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorsStakeInQuorumsAtBlock", reflect.TypeOf((*MockAvsReaderer)(nil).GetOperatorsStakeInQuorumsAtBlock), arg0, arg1, arg2) +} + +// GetOperatorsStakeInQuorumsAtCurrentBlock mocks base method. +func (m *MockAvsReaderer) GetOperatorsStakeInQuorumsAtCurrentBlock(arg0 *bind.CallOpts, arg1 types.QuorumNums) ([][]contractOperatorStateRetriever.OperatorStateRetrieverOperator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOperatorsStakeInQuorumsAtCurrentBlock", arg0, arg1) + ret0, _ := ret[0].([][]contractOperatorStateRetriever.OperatorStateRetrieverOperator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetOperatorsStakeInQuorumsAtCurrentBlock indicates an expected call of GetOperatorsStakeInQuorumsAtCurrentBlock. +func (mr *MockAvsReadererMockRecorder) GetOperatorsStakeInQuorumsAtCurrentBlock(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorsStakeInQuorumsAtCurrentBlock", reflect.TypeOf((*MockAvsReaderer)(nil).GetOperatorsStakeInQuorumsAtCurrentBlock), arg0, arg1) +} + +// GetOperatorsStakeInQuorumsOfOperatorAtBlock mocks base method. +func (m *MockAvsReaderer) GetOperatorsStakeInQuorumsOfOperatorAtBlock(arg0 *bind.CallOpts, arg1 types.Bytes32, arg2 uint32) (types.QuorumNums, [][]contractOperatorStateRetriever.OperatorStateRetrieverOperator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOperatorsStakeInQuorumsOfOperatorAtBlock", arg0, arg1, arg2) + ret0, _ := ret[0].(types.QuorumNums) + ret1, _ := ret[1].([][]contractOperatorStateRetriever.OperatorStateRetrieverOperator) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetOperatorsStakeInQuorumsOfOperatorAtBlock indicates an expected call of GetOperatorsStakeInQuorumsOfOperatorAtBlock. +func (mr *MockAvsReadererMockRecorder) GetOperatorsStakeInQuorumsOfOperatorAtBlock(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorsStakeInQuorumsOfOperatorAtBlock", reflect.TypeOf((*MockAvsReaderer)(nil).GetOperatorsStakeInQuorumsOfOperatorAtBlock), arg0, arg1, arg2) +} + +// GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock mocks base method. +func (m *MockAvsReaderer) GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock(arg0 *bind.CallOpts, arg1 types.Bytes32) (types.QuorumNums, [][]contractOperatorStateRetriever.OperatorStateRetrieverOperator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock", arg0, arg1) + ret0, _ := ret[0].(types.QuorumNums) + ret1, _ := ret[1].([][]contractOperatorStateRetriever.OperatorStateRetrieverOperator) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock indicates an expected call of GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock. +func (mr *MockAvsReadererMockRecorder) GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock", reflect.TypeOf((*MockAvsReaderer)(nil).GetOperatorsStakeInQuorumsOfOperatorAtCurrentBlock), arg0, arg1) +} + +// GetQuorumCount mocks base method. +func (m *MockAvsReaderer) GetQuorumCount(arg0 *bind.CallOpts) (byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetQuorumCount", arg0) + ret0, _ := ret[0].(byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetQuorumCount indicates an expected call of GetQuorumCount. +func (mr *MockAvsReadererMockRecorder) GetQuorumCount(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQuorumCount", reflect.TypeOf((*MockAvsReaderer)(nil).GetQuorumCount), arg0) +} + +// IsOperatorRegistered mocks base method. +func (m *MockAvsReaderer) IsOperatorRegistered(arg0 *bind.CallOpts, arg1 common.Address) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsOperatorRegistered", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// IsOperatorRegistered indicates an expected call of IsOperatorRegistered. +func (mr *MockAvsReadererMockRecorder) IsOperatorRegistered(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsOperatorRegistered", reflect.TypeOf((*MockAvsReaderer)(nil).IsOperatorRegistered), arg0, arg1) +} + +// QueryExistingRegisteredOperatorPubKeys mocks base method. +func (m *MockAvsReaderer) QueryExistingRegisteredOperatorPubKeys(arg0 context.Context, arg1, arg2 *big.Int) ([]common.Address, []types.OperatorPubkeys, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryExistingRegisteredOperatorPubKeys", arg0, arg1, arg2) + ret0, _ := ret[0].([]common.Address) + ret1, _ := ret[1].([]types.OperatorPubkeys) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// QueryExistingRegisteredOperatorPubKeys indicates an expected call of QueryExistingRegisteredOperatorPubKeys. +func (mr *MockAvsReadererMockRecorder) QueryExistingRegisteredOperatorPubKeys(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryExistingRegisteredOperatorPubKeys", reflect.TypeOf((*MockAvsReaderer)(nil).QueryExistingRegisteredOperatorPubKeys), arg0, arg1, arg2) +} + +// QueryExistingRegisteredOperatorSockets mocks base method. +func (m *MockAvsReaderer) QueryExistingRegisteredOperatorSockets(arg0 context.Context, arg1, arg2 *big.Int) (map[types.Bytes32]types.Socket, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "QueryExistingRegisteredOperatorSockets", arg0, arg1, arg2) + ret0, _ := ret[0].(map[types.Bytes32]types.Socket) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// QueryExistingRegisteredOperatorSockets indicates an expected call of QueryExistingRegisteredOperatorSockets. +func (mr *MockAvsReadererMockRecorder) QueryExistingRegisteredOperatorSockets(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryExistingRegisteredOperatorSockets", reflect.TypeOf((*MockAvsReaderer)(nil).QueryExistingRegisteredOperatorSockets), arg0, arg1, arg2) +} diff --git a/temp-incredible-squaring-avs/core/chainio/mocks/avs_subscriber.go b/temp-incredible-squaring-avs/core/chainio/mocks/avs_subscriber.go new file mode 100644 index 0000000..5f11449 --- /dev/null +++ b/temp-incredible-squaring-avs/core/chainio/mocks/avs_subscriber.go @@ -0,0 +1,84 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/Layr-Labs/incredible-squaring-avs/core/chainio (interfaces: AvsSubscriberer) +// +// Generated by this command: +// +// mockgen -destination=./mocks/avs_subscriber.go -package=mocks github.com/Layr-Labs/incredible-squaring-avs/core/chainio AvsSubscriberer +// +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + contractIncredibleSquaringTaskManager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + types "github.com/ethereum/go-ethereum/core/types" + event "github.com/ethereum/go-ethereum/event" + gomock "go.uber.org/mock/gomock" +) + +// MockAvsSubscriberer is a mock of AvsSubscriberer interface. +type MockAvsSubscriberer struct { + ctrl *gomock.Controller + recorder *MockAvsSubscribererMockRecorder +} + +// MockAvsSubscribererMockRecorder is the mock recorder for MockAvsSubscriberer. +type MockAvsSubscribererMockRecorder struct { + mock *MockAvsSubscriberer +} + +// NewMockAvsSubscriberer creates a new mock instance. +func NewMockAvsSubscriberer(ctrl *gomock.Controller) *MockAvsSubscriberer { + mock := &MockAvsSubscriberer{ctrl: ctrl} + mock.recorder = &MockAvsSubscribererMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockAvsSubscriberer) EXPECT() *MockAvsSubscribererMockRecorder { + return m.recorder +} + +// ParseTaskResponded mocks base method. +func (m *MockAvsSubscriberer) ParseTaskResponded(arg0 types.Log) (*contractIncredibleSquaringTaskManager.ContractIncredibleSquaringTaskManagerTaskResponded, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ParseTaskResponded", arg0) + ret0, _ := ret[0].(*contractIncredibleSquaringTaskManager.ContractIncredibleSquaringTaskManagerTaskResponded) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ParseTaskResponded indicates an expected call of ParseTaskResponded. +func (mr *MockAvsSubscribererMockRecorder) ParseTaskResponded(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParseTaskResponded", reflect.TypeOf((*MockAvsSubscriberer)(nil).ParseTaskResponded), arg0) +} + +// SubscribeToNewTasks mocks base method. +func (m *MockAvsSubscriberer) SubscribeToNewTasks(arg0 chan *contractIncredibleSquaringTaskManager.ContractIncredibleSquaringTaskManagerNewTaskCreated) event.Subscription { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SubscribeToNewTasks", arg0) + ret0, _ := ret[0].(event.Subscription) + return ret0 +} + +// SubscribeToNewTasks indicates an expected call of SubscribeToNewTasks. +func (mr *MockAvsSubscribererMockRecorder) SubscribeToNewTasks(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeToNewTasks", reflect.TypeOf((*MockAvsSubscriberer)(nil).SubscribeToNewTasks), arg0) +} + +// SubscribeToTaskResponses mocks base method. +func (m *MockAvsSubscriberer) SubscribeToTaskResponses(arg0 chan *contractIncredibleSquaringTaskManager.ContractIncredibleSquaringTaskManagerTaskResponded) event.Subscription { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SubscribeToTaskResponses", arg0) + ret0, _ := ret[0].(event.Subscription) + return ret0 +} + +// SubscribeToTaskResponses indicates an expected call of SubscribeToTaskResponses. +func (mr *MockAvsSubscribererMockRecorder) SubscribeToTaskResponses(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeToTaskResponses", reflect.TypeOf((*MockAvsSubscriberer)(nil).SubscribeToTaskResponses), arg0) +} diff --git a/temp-incredible-squaring-avs/core/chainio/mocks/avs_writer.go b/temp-incredible-squaring-avs/core/chainio/mocks/avs_writer.go new file mode 100644 index 0000000..860a6cf --- /dev/null +++ b/temp-incredible-squaring-avs/core/chainio/mocks/avs_writer.go @@ -0,0 +1,153 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/Layr-Labs/incredible-squaring-avs/core/chainio (interfaces: AvsWriterer) +// +// Generated by this command: +// +// mockgen -destination=./mocks/avs_writer.go -package=mocks github.com/Layr-Labs/incredible-squaring-avs/core/chainio AvsWriterer +// +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + ecdsa "crypto/ecdsa" + big "math/big" + reflect "reflect" + + contractRegistryCoordinator "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator" + bls "github.com/Layr-Labs/eigensdk-go/crypto/bls" + types "github.com/Layr-Labs/eigensdk-go/types" + contractIncredibleSquaringTaskManager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + common "github.com/ethereum/go-ethereum/common" + types0 "github.com/ethereum/go-ethereum/core/types" + gomock "go.uber.org/mock/gomock" +) + +// MockAvsWriterer is a mock of AvsWriterer interface. +type MockAvsWriterer struct { + ctrl *gomock.Controller + recorder *MockAvsWritererMockRecorder +} + +// MockAvsWritererMockRecorder is the mock recorder for MockAvsWriterer. +type MockAvsWritererMockRecorder struct { + mock *MockAvsWriterer +} + +// NewMockAvsWriterer creates a new mock instance. +func NewMockAvsWriterer(ctrl *gomock.Controller) *MockAvsWriterer { + mock := &MockAvsWriterer{ctrl: ctrl} + mock.recorder = &MockAvsWritererMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockAvsWriterer) EXPECT() *MockAvsWritererMockRecorder { + return m.recorder +} + +// DeregisterOperator mocks base method. +func (m *MockAvsWriterer) DeregisterOperator(arg0 context.Context, arg1 types.QuorumNums, arg2 contractRegistryCoordinator.BN254G1Point) (*types0.Receipt, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeregisterOperator", arg0, arg1, arg2) + ret0, _ := ret[0].(*types0.Receipt) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeregisterOperator indicates an expected call of DeregisterOperator. +func (mr *MockAvsWritererMockRecorder) DeregisterOperator(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeregisterOperator", reflect.TypeOf((*MockAvsWriterer)(nil).DeregisterOperator), arg0, arg1, arg2) +} + +// RaiseChallenge mocks base method. +func (m *MockAvsWriterer) RaiseChallenge(arg0 context.Context, arg1 contractIncredibleSquaringTaskManager.IIncredibleSquaringTaskManagerTask, arg2 contractIncredibleSquaringTaskManager.IIncredibleSquaringTaskManagerTaskResponse, arg3 contractIncredibleSquaringTaskManager.IIncredibleSquaringTaskManagerTaskResponseMetadata, arg4 []contractIncredibleSquaringTaskManager.BN254G1Point) (*types0.Receipt, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RaiseChallenge", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(*types0.Receipt) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RaiseChallenge indicates an expected call of RaiseChallenge. +func (mr *MockAvsWritererMockRecorder) RaiseChallenge(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RaiseChallenge", reflect.TypeOf((*MockAvsWriterer)(nil).RaiseChallenge), arg0, arg1, arg2, arg3, arg4) +} + +// RegisterOperatorInQuorumWithAVSRegistryCoordinator mocks base method. +func (m *MockAvsWriterer) RegisterOperatorInQuorumWithAVSRegistryCoordinator(arg0 context.Context, arg1 *ecdsa.PrivateKey, arg2 [32]byte, arg3 *big.Int, arg4 *bls.KeyPair, arg5 types.QuorumNums, arg6 string) (*types0.Receipt, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RegisterOperatorInQuorumWithAVSRegistryCoordinator", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret0, _ := ret[0].(*types0.Receipt) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RegisterOperatorInQuorumWithAVSRegistryCoordinator indicates an expected call of RegisterOperatorInQuorumWithAVSRegistryCoordinator. +func (mr *MockAvsWritererMockRecorder) RegisterOperatorInQuorumWithAVSRegistryCoordinator(arg0, arg1, arg2, arg3, arg4, arg5, arg6 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterOperatorInQuorumWithAVSRegistryCoordinator", reflect.TypeOf((*MockAvsWriterer)(nil).RegisterOperatorInQuorumWithAVSRegistryCoordinator), arg0, arg1, arg2, arg3, arg4, arg5, arg6) +} + +// SendAggregatedResponse mocks base method. +func (m *MockAvsWriterer) SendAggregatedResponse(arg0 context.Context, arg1 contractIncredibleSquaringTaskManager.IIncredibleSquaringTaskManagerTask, arg2 contractIncredibleSquaringTaskManager.IIncredibleSquaringTaskManagerTaskResponse, arg3 contractIncredibleSquaringTaskManager.IBLSSignatureCheckerNonSignerStakesAndSignature) (*types0.Receipt, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendAggregatedResponse", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*types0.Receipt) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SendAggregatedResponse indicates an expected call of SendAggregatedResponse. +func (mr *MockAvsWritererMockRecorder) SendAggregatedResponse(arg0, arg1, arg2, arg3 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAggregatedResponse", reflect.TypeOf((*MockAvsWriterer)(nil).SendAggregatedResponse), arg0, arg1, arg2, arg3) +} + +// SendNewTaskNumberToSquare mocks base method. +func (m *MockAvsWriterer) SendNewTaskNumberToSquare(arg0 context.Context, arg1 *big.Int, arg2 types.QuorumThresholdPercentage, arg3 types.QuorumNums) (contractIncredibleSquaringTaskManager.IIncredibleSquaringTaskManagerTask, uint32, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendNewTaskNumberToSquare", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(contractIncredibleSquaringTaskManager.IIncredibleSquaringTaskManagerTask) + ret1, _ := ret[1].(uint32) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// SendNewTaskNumberToSquare indicates an expected call of SendNewTaskNumberToSquare. +func (mr *MockAvsWritererMockRecorder) SendNewTaskNumberToSquare(arg0, arg1, arg2, arg3 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendNewTaskNumberToSquare", reflect.TypeOf((*MockAvsWriterer)(nil).SendNewTaskNumberToSquare), arg0, arg1, arg2, arg3) +} + +// UpdateStakesOfEntireOperatorSetForQuorums mocks base method. +func (m *MockAvsWriterer) UpdateStakesOfEntireOperatorSetForQuorums(arg0 context.Context, arg1 [][]common.Address, arg2 types.QuorumNums) (*types0.Receipt, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStakesOfEntireOperatorSetForQuorums", arg0, arg1, arg2) + ret0, _ := ret[0].(*types0.Receipt) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateStakesOfEntireOperatorSetForQuorums indicates an expected call of UpdateStakesOfEntireOperatorSetForQuorums. +func (mr *MockAvsWritererMockRecorder) UpdateStakesOfEntireOperatorSetForQuorums(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStakesOfEntireOperatorSetForQuorums", reflect.TypeOf((*MockAvsWriterer)(nil).UpdateStakesOfEntireOperatorSetForQuorums), arg0, arg1, arg2) +} + +// UpdateStakesOfOperatorSubsetForAllQuorums mocks base method. +func (m *MockAvsWriterer) UpdateStakesOfOperatorSubsetForAllQuorums(arg0 context.Context, arg1 []common.Address) (*types0.Receipt, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStakesOfOperatorSubsetForAllQuorums", arg0, arg1) + ret0, _ := ret[0].(*types0.Receipt) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateStakesOfOperatorSubsetForAllQuorums indicates an expected call of UpdateStakesOfOperatorSubsetForAllQuorums. +func (mr *MockAvsWritererMockRecorder) UpdateStakesOfOperatorSubsetForAllQuorums(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStakesOfOperatorSubsetForAllQuorums", reflect.TypeOf((*MockAvsWriterer)(nil).UpdateStakesOfOperatorSubsetForAllQuorums), arg0, arg1) +} diff --git a/temp-incredible-squaring-avs/core/chainio/mocks/tmp.go b/temp-incredible-squaring-avs/core/chainio/mocks/tmp.go new file mode 100644 index 0000000..ddef246 --- /dev/null +++ b/temp-incredible-squaring-avs/core/chainio/mocks/tmp.go @@ -0,0 +1,4 @@ +package mocks + +// TODO: delete me (just added this temporarily so that go mod tidy wouldn't complain +// about this package not existing, until we fix the code so that make mocks works) diff --git a/temp-incredible-squaring-avs/core/config/config.go b/temp-incredible-squaring-avs/core/config/config.go new file mode 100644 index 0000000..70f5454 --- /dev/null +++ b/temp-incredible-squaring-avs/core/config/config.go @@ -0,0 +1,194 @@ +package config + +import ( + "context" + "crypto/ecdsa" + "errors" + "os" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/urfave/cli" + + "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" + "github.com/Layr-Labs/eigensdk-go/chainio/clients/wallet" + "github.com/Layr-Labs/eigensdk-go/chainio/txmgr" + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + sdklogging "github.com/Layr-Labs/eigensdk-go/logging" + "github.com/Layr-Labs/eigensdk-go/signerv2" + + sdkutils "github.com/Layr-Labs/eigensdk-go/utils" +) + +// Config contains all of the configuration information for a credible squaring aggregators and challengers. +// Operators use a separate config. (see config-files/operator.anvil.yaml) +type Config struct { + EcdsaPrivateKey *ecdsa.PrivateKey + BlsPrivateKey *bls.PrivateKey + Logger sdklogging.Logger + EigenMetricsIpPortAddress string + // we need the url for the eigensdk currently... eventually standardize api so as to + // only take an ethclient or an rpcUrl (and build the ethclient at each constructor site) + EthHttpRpcUrl string + EthWsRpcUrl string + EthHttpClient eth.Client + EthWsClient eth.Client + OperatorStateRetrieverAddr common.Address + IncredibleSquaringRegistryCoordinatorAddr common.Address + AggregatorServerIpPortAddr string + RegisterOperatorOnStartup bool + // json:"-" skips this field when marshaling (only used for logging to stdout), since SignerFn doesnt implement marshalJson + SignerFn signerv2.SignerFn `json:"-"` + TxMgr txmgr.TxManager + AggregatorAddress common.Address +} + +// These are read from ConfigFileFlag +type ConfigRaw struct { + Environment sdklogging.LogLevel `yaml:"environment"` + EthRpcUrl string `yaml:"eth_rpc_url"` + EthWsUrl string `yaml:"eth_ws_url"` + AggregatorServerIpPortAddr string `yaml:"aggregator_server_ip_port_address"` + RegisterOperatorOnStartup bool `yaml:"register_operator_on_startup"` +} + +// These are read from CredibleSquaringDeploymentFileFlag +type IncredibleSquaringDeploymentRaw struct { + Addresses IncredibleSquaringContractsRaw `json:"addresses"` +} +type IncredibleSquaringContractsRaw struct { + RegistryCoordinatorAddr string `json:"registryCoordinator"` + OperatorStateRetrieverAddr string `json:"operatorStateRetriever"` +} + +// NewConfig parses config file to read from from flags or environment variables +// Note: This config is shared by challenger and aggregator and so we put in the core. +// Operator has a different config and is meant to be used by the operator CLI. +func NewConfig(ctx *cli.Context) (*Config, error) { + + var configRaw ConfigRaw + configFilePath := ctx.GlobalString(ConfigFileFlag.Name) + if configFilePath != "" { + sdkutils.ReadYamlConfig(configFilePath, &configRaw) + } + + var credibleSquaringDeploymentRaw IncredibleSquaringDeploymentRaw + credibleSquaringDeploymentFilePath := ctx.GlobalString(CredibleSquaringDeploymentFileFlag.Name) + if _, err := os.Stat(credibleSquaringDeploymentFilePath); errors.Is(err, os.ErrNotExist) { + panic("Path " + credibleSquaringDeploymentFilePath + " does not exist") + } + sdkutils.ReadJsonConfig(credibleSquaringDeploymentFilePath, &credibleSquaringDeploymentRaw) + + logger, err := sdklogging.NewZapLogger(configRaw.Environment) + if err != nil { + return nil, err + } + + ethRpcClient, err := eth.NewClient(configRaw.EthRpcUrl) + if err != nil { + logger.Errorf("Cannot create http ethclient", "err", err) + return nil, err + } + + ethWsClient, err := eth.NewClient(configRaw.EthWsUrl) + if err != nil { + logger.Errorf("Cannot create ws ethclient", "err", err) + return nil, err + } + + ecdsaPrivateKeyString := ctx.GlobalString(EcdsaPrivateKeyFlag.Name) + if ecdsaPrivateKeyString[:2] == "0x" { + ecdsaPrivateKeyString = ecdsaPrivateKeyString[2:] + } + ecdsaPrivateKey, err := crypto.HexToECDSA(ecdsaPrivateKeyString) + if err != nil { + logger.Errorf("Cannot parse ecdsa private key", "err", err) + return nil, err + } + + aggregatorAddr, err := sdkutils.EcdsaPrivateKeyToAddress(ecdsaPrivateKey) + if err != nil { + logger.Error("Cannot get operator address", "err", err) + return nil, err + } + + chainId, err := ethRpcClient.ChainID(context.Background()) + if err != nil { + logger.Error("Cannot get chainId", "err", err) + return nil, err + } + + signerV2, _, err := signerv2.SignerFromConfig(signerv2.Config{PrivateKey: ecdsaPrivateKey}, chainId) + if err != nil { + panic(err) + } + skWallet, err := wallet.NewPrivateKeyWallet(ethRpcClient, signerV2, aggregatorAddr, logger) + if err != nil { + panic(err) + } + txMgr := txmgr.NewSimpleTxManager(skWallet, ethRpcClient, logger, aggregatorAddr) + + config := &Config{ + EcdsaPrivateKey: ecdsaPrivateKey, + Logger: logger, + EthWsRpcUrl: configRaw.EthWsUrl, + EthHttpRpcUrl: configRaw.EthRpcUrl, + EthHttpClient: ethRpcClient, + EthWsClient: ethWsClient, + OperatorStateRetrieverAddr: common.HexToAddress(credibleSquaringDeploymentRaw.Addresses.OperatorStateRetrieverAddr), + IncredibleSquaringRegistryCoordinatorAddr: common.HexToAddress(credibleSquaringDeploymentRaw.Addresses.RegistryCoordinatorAddr), + AggregatorServerIpPortAddr: configRaw.AggregatorServerIpPortAddr, + RegisterOperatorOnStartup: configRaw.RegisterOperatorOnStartup, + SignerFn: signerV2, + TxMgr: txMgr, + AggregatorAddress: aggregatorAddr, + } + config.validate() + return config, nil +} + +func (c *Config) validate() { + // TODO: make sure every pointer is non-nil + if c.OperatorStateRetrieverAddr == common.HexToAddress("") { + panic("Config: BLSOperatorStateRetrieverAddr is required") + } + if c.IncredibleSquaringRegistryCoordinatorAddr == common.HexToAddress("") { + panic("Config: IncredibleSquaringRegistryCoordinatorAddr is required") + } +} + +var ( + /* Required Flags */ + ConfigFileFlag = cli.StringFlag{ + Name: "config", + Required: true, + Usage: "Load configuration from `FILE`", + } + CredibleSquaringDeploymentFileFlag = cli.StringFlag{ + Name: "credible-squaring-deployment", + Required: true, + Usage: "Load credible squaring contract addresses from `FILE`", + } + EcdsaPrivateKeyFlag = cli.StringFlag{ + Name: "ecdsa-private-key", + Usage: "Ethereum private key", + Required: true, + EnvVar: "ECDSA_PRIVATE_KEY", + } + /* Optional Flags */ +) + +var requiredFlags = []cli.Flag{ + ConfigFileFlag, + CredibleSquaringDeploymentFileFlag, + EcdsaPrivateKeyFlag, +} + +var optionalFlags = []cli.Flag{} + +func init() { + Flags = append(requiredFlags, optionalFlags...) +} + +// Flags contains the list of configuration options available to the binary. +var Flags []cli.Flag diff --git a/temp-incredible-squaring-avs/core/utils.go b/temp-incredible-squaring-avs/core/utils.go new file mode 100644 index 0000000..98b559f --- /dev/null +++ b/temp-incredible-squaring-avs/core/utils.go @@ -0,0 +1,79 @@ +package core + +import ( + "math/big" + + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + "github.com/ethereum/go-ethereum/accounts/abi" + "golang.org/x/crypto/sha3" +) + +// this hardcodes abi.encode() for cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse +// unclear why abigen doesn't provide this out of the box... +func AbiEncodeTaskResponse(h *cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse) ([]byte, error) { + + // The order here has to match the field ordering of cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse + taskResponseType, err := abi.NewType("tuple", "", []abi.ArgumentMarshaling{ + { + Name: "referenceTaskIndex", + Type: "uint32", + }, + { + Name: "numberSquared", + Type: "uint256", + }, + }) + if err != nil { + return nil, err + } + arguments := abi.Arguments{ + { + Type: taskResponseType, + }, + } + + bytes, err := arguments.Pack(h) + if err != nil { + return nil, err + } + + return bytes, nil +} + +// GetTaskResponseDigest returns the hash of the TaskResponse, which is what operators sign over +func GetTaskResponseDigest(h *cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse) ([32]byte, error) { + + encodeTaskResponseByte, err := AbiEncodeTaskResponse(h) + if err != nil { + return [32]byte{}, err + } + + var taskResponseDigest [32]byte + hasher := sha3.NewLegacyKeccak256() + hasher.Write(encodeTaskResponseByte) + copy(taskResponseDigest[:], hasher.Sum(nil)[:32]) + + return taskResponseDigest, nil +} + +// BINDING UTILS - conversion from contract structs to golang structs + +// BN254.sol is a library, so bindings for G1 Points and G2 Points are only generated +// in every contract that imports that library. Thus the output here will need to be +// type casted if G1Point is needed to interface with another contract (eg: BLSPublicKeyCompendium.sol) +func ConvertToBN254G1Point(input *bls.G1Point) cstaskmanager.BN254G1Point { + output := cstaskmanager.BN254G1Point{ + X: input.X.BigInt(big.NewInt(0)), + Y: input.Y.BigInt(big.NewInt(0)), + } + return output +} + +func ConvertToBN254G2Point(input *bls.G2Point) cstaskmanager.BN254G2Point { + output := cstaskmanager.BN254G2Point{ + X: [2]*big.Int{input.X.A1.BigInt(big.NewInt(0)), input.X.A0.BigInt(big.NewInt(0))}, + Y: [2]*big.Int{input.Y.A1.BigInt(big.NewInt(0)), input.Y.A0.BigInt(big.NewInt(0))}, + } + return output +} diff --git a/temp-incredible-squaring-avs/diagrams/architecture.png b/temp-incredible-squaring-avs/diagrams/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..3bbaaf87b6b7f8db361a215d3cf18d2507ed4104 GIT binary patch literal 59577 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 TXAzzO|0%*$WuIL)d-Q(*QCFsD literal 0 HcmV?d00001 diff --git a/temp-incredible-squaring-avs/docker-compose-build.yaml b/temp-incredible-squaring-avs/docker-compose-build.yaml new file mode 100644 index 0000000..de552f6 --- /dev/null +++ b/temp-incredible-squaring-avs/docker-compose-build.yaml @@ -0,0 +1,12 @@ +# This file is used for building and pushing images +services: + node: + build: + context: . + dockerfile: operator.Dockerfile + image: ghcr.io/layr-labs/incredible-squaring-avs/node:latest + nodeplugin: + build: + context: . + dockerfile: plugin.Dockerfile + image: ghcr.io/layr-labs/incredible-squaring-avs/nodeplugin:latest diff --git a/temp-incredible-squaring-avs/docker-compose.yml b/temp-incredible-squaring-avs/docker-compose.yml new file mode 100644 index 0000000..3760d7a --- /dev/null +++ b/temp-incredible-squaring-avs/docker-compose.yml @@ -0,0 +1,131 @@ +version: "3" + +networks: + incredible-squaring-network: + name: incredible-squaring-network + driver: bridge + +services: + anvil: + image: ghcr.io/foundry-rs/foundry:nightly-5b7e4cb3c882b28f3c32ba580de27ce7381f415a + container_name: anvil + ports: + # opening the port so we can easily cast to anvil from localhost + - "8545:8545" + # changed entrypoint because the default 'bash -c' entrypoint wasn't working the intended way... + entrypoint: anvil + volumes: + - ./tests/anvil/avs-and-eigenlayer-deployed-anvil-state.json:/root/.anvil/state.json + command: --host 0.0.0.0 --load-state /root/.anvil/state.json + networks: + - incredible-squaring-network + + anvil-advance-chain-script: + image: ghcr.io/foundry-rs/foundry:nightly-5b7e4cb3c882b28f3c32ba580de27ce7381f415a + depends_on: + - anvil + entrypoint: cast + command: rpc anvil_mine 100 --rpc-url http://anvil:8545 + networks: + - incredible-squaring-network + + aggregator: + image: ghcr.io/layr-labs/incredible-squaring/aggregator/cmd/main.go:latest + container_name: incredible-squaring-aggregator + depends_on: + anvil: + condition: service_started + anvil-advance-chain-script: + condition: service_completed_successfully + volumes: + - ./:/incredible-squaring/ + working_dir: /incredible-squaring + command: + - --config + - config-files/aggregator-docker-compose.yaml + - --credible-squaring-deployment + - contracts/script/output/31337/credible_squaring_avs_deployment_output.json + - --ecdsa-private-key + - "0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6" + networks: + - incredible-squaring-network + + operator1: + image: ghcr.io/layr-labs/incredible-squaring/operator/cmd/main.go:latest + container_name: incredible-squaring-operator1 + depends_on: + anvil: + condition: service_started + aggregator: + condition: service_started + anvil-advance-chain-script: + condition: service_completed_successfully + ports: + - "9090:9090" # prometheus metrics port (defined in operator-docker-compose.anvil.yaml file) + volumes: + - ./:/incredible-squaring/ + working_dir: /incredible-squaring + command: --config config-files/operator-docker-compose.anvil.yaml + networks: + - incredible-squaring-network + + # operator2: + # image: ghcr.io/layr-labs/incredible-squaring/operator/cmd/main.go:latest + # container_name: incredible-squaring-operator2 + # depends_on: + # anvil: + # condition: service_started + # volumes: + # - ./:/incredible-squaring/ + # working_dir: /incredible-squaring + # command: --config config-files/operator-docker-compose.anvil.yaml --credible-squaring-deployment contracts/script/output/31337/credible_squaring_avs_deployment_output.json --ecdsa-private-key 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d --bls-private-key 2 + # networks: + # - incredible-squaring-network + + # METRICS RELATED + grafana: + image: grafana/grafana:9.4.1 + container_name: grafana + volumes: + - grafana_data:/var/lib/grafana + - ./grafana/provisioning:/etc/grafana/provisioning + environment: + # See https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#override-configuration-with-environment-variables + # and https://grafana.com/docs/grafana/latest/setup-grafana/configure-docker/ + # They recommend using env vars instead of overwriting config.ini + - GF_SECURITY_ADMIN_USER=${ADMIN_USER:-admin} + - GF_SECURITY_ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin} + - GF_USERS_ALLOW_SIGN_UP=false + restart: unless-stopped + ports: + - 3000:3000 + networks: + - incredible-squaring-network + + prometheus: + image: prom/prometheus:v2.42.0 + container_name: prometheus + volumes: + - ./prometheus:/etc/prometheus + - prometheus_data:/prometheus + command: + - "--config.file=/etc/prometheus/prometheus.yml" + - "--storage.tsdb.path=/prometheus" + - "--web.console.libraries=/etc/prometheus/console_libraries" + - "--web.console.templates=/etc/prometheus/consoles" + - "--storage.tsdb.retention.time=200h" + - "--web.enable-lifecycle" + - --web.enable-remote-write-receiver + restart: unless-stopped + expose: + - 9090 + networks: + - incredible-squaring-network + # so that we can access the host from within the container + # needed to get the metrics from host.docker.internal:9184/metrics + extra_hosts: + - "host.docker.internal:host-gateway" + +volumes: + prometheus_data: {} + grafana_data: {} diff --git a/temp-incredible-squaring-avs/go.mod b/temp-incredible-squaring-avs/go.mod new file mode 100644 index 0000000..476190d --- /dev/null +++ b/temp-incredible-squaring-avs/go.mod @@ -0,0 +1,140 @@ +module github.com/Layr-Labs/incredible-squaring-avs + +go 1.21 + +toolchain go1.21.0 + +require ( + github.com/Layr-Labs/eigensdk-go v0.1.7-0.20240425202952-954cd7661775 + github.com/ethereum/go-ethereum v1.13.14 + github.com/prometheus/client_golang v1.19.0 + github.com/stretchr/testify v1.9.0 + github.com/testcontainers/testcontainers-go v0.29.1 + github.com/urfave/cli v1.22.14 + go.uber.org/mock v0.4.0 + golang.org/x/crypto v0.18.0 +) + +require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/DataDog/zstd v1.5.2 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/StackExchange/wmi v1.2.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.10.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect + github.com/cockroachdb/redact v1.1.3 // 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.1 // indirect + github.com/containerd/containerd v1.7.12 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/cpuguy83/dockercfg v0.3.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/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.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/docker/docker v25.0.3+incompatible // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/fjl/memsize v0.0.2 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // 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-logr/logr v1.2.4 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/gofrs/flock v0.8.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/hashicorp/go-bexpr v0.1.10 // indirect + github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect + github.com/holiman/bloomfilter/v2 v2.0.3 // indirect + github.com/holiman/uint256 v1.2.4 // indirect + github.com/huin/goupnp v1.3.0 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/klauspost/compress v1.16.0 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/lmittmann/tint v1.0.4 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/mitchellh/pointerstructure v1.2.0 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/moby/patternmatcher v0.6.0 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/sys/user v0.1.0 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/morikuni/aec v1.0.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // 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.2.0 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/rs/cors v1.7.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect + github.com/shirou/gopsutil/v3 v3.23.12 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/status-im/keycard-go v0.2.0 // indirect + github.com/supranational/blst v0.3.11 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // 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.3 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect + golang.org/x/mod v0.16.0 // indirect + golang.org/x/sync v0.5.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.15.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + google.golang.org/grpc v1.58.3 // indirect + google.golang.org/protobuf v1.32.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + rsc.io/tmplfunc v0.0.3 // indirect +) + +// use this when making changes to eigensdk locally +// replace github.com/Layr-Labs/eigensdk-go => ../eigensdk-go diff --git a/temp-incredible-squaring-avs/go.sum b/temp-incredible-squaring-avs/go.sum new file mode 100644 index 0000000..a6a98f4 --- /dev/null +++ b/temp-incredible-squaring-avs/go.sum @@ -0,0 +1,657 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +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/Layr-Labs/eigensdk-go v0.1.7-0.20240425202952-954cd7661775 h1:xQQ4xnlzO1n0nU2HPizd00H2N3zacJjbSPwLhOHxZEo= +github.com/Layr-Labs/eigensdk-go v0.1.7-0.20240425202952-954cd7661775/go.mod h1:ECU8/Ocsf+dGcN2rs8I1PScq4dOkQqY+vgwnq30Ov4M= +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.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= +github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= +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/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +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.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= +github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +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.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +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/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/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-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= +github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/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/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +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.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= +github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +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/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= +github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +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-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/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +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/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +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/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v25.0.3+incompatible h1:D5fy/lYmY7bvZa0XTZ5/UJPljor41F+vdyJG5luQLfQ= +github.com/docker/docker v25.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +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/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/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.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +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/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.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ= +github.com/ethereum/go-ethereum v1.13.14/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU= +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/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA= +github.com/fjl/memsize v0.0.2/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.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/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.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/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-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-logr/logr v1.2.2/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.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +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-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +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.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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +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.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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +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= +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= +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.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.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-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/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +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.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +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/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/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.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.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +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/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +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/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.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +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/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/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +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/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/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= +github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +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/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-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/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +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/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/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/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/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= +github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +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/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +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/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 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +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.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +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/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +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.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 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +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/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 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +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.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4= +github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +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.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +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.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/testcontainers/testcontainers-go v0.29.1 h1:z8kxdFlovA2y97RWx98v/TQ+tR+SXZm6p35M+xB92zk= +github.com/testcontainers/testcontainers-go v0.29.1/go.mod h1:SnKnKQav8UcgtKqjp/AD8bE1MqZm+3TDb/B8crE3XnI= +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/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +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.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= +github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= +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/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/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/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/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/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= +go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +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/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +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.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +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.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.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-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-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-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.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-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +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-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +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-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.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.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-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-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/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-20201204225414-ed752295db88/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-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-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-20220209214540-3681064d5158/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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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.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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +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.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-20201208040808-7e3f01d25324/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-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-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +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= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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/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-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-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g= +google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw= +google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +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= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +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.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/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +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/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/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= +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= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/temp-incredible-squaring-avs/grafana/provisioning/dashboards/AVSs/incredible_squaring.json b/temp-incredible-squaring-avs/grafana/provisioning/dashboards/AVSs/incredible_squaring.json new file mode 100644 index 0000000..94893d3 --- /dev/null +++ b/temp-incredible-squaring-avs/grafana/provisioning/dashboards/AVSs/incredible_squaring.json @@ -0,0 +1,326 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 2, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "builder", + "expr": "incsq_num_tasks_received", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "New Tasks Received", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "builder", + "expr": "incsq_num_signed_task_responses_accepted_by_aggregator", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Signed Tasks Responses", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "builder", + "expr": "eigen_performance_score{avs_name=\"incredible-squaring\"}", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Performance Score", + "type": "timeseries" + } + ], + "refresh": "10s", + "revision": 1, + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Incredible Squaring", + "uid": "vgD8u1U4z", + "version": 2, + "weekStart": "" +} \ No newline at end of file diff --git a/temp-incredible-squaring-avs/grafana/provisioning/dashboards/dashboard_provider.yml b/temp-incredible-squaring-avs/grafana/provisioning/dashboards/dashboard_provider.yml new file mode 100644 index 0000000..1caea93 --- /dev/null +++ b/temp-incredible-squaring-avs/grafana/provisioning/dashboards/dashboard_provider.yml @@ -0,0 +1,17 @@ +apiVersion: 1 + +# dashboard providers +# we use a single generic one for now. +# we could split this into a provider for sui bot related, and one for general purpose, etc eventually +# see https://grafana.com/docs/grafana/latest/administration/provisioning/#dashboards +providers: + - name: 'Local Files' + folder: '' # General is the default + type: file + disableDeletion: false + editable: true + allowUiUpdates: true + updateIntervalSeconds: 10 + options: + path: /etc/grafana/provisioning/dashboards + foldersFromFilesStructure: true \ No newline at end of file diff --git a/temp-incredible-squaring-avs/grafana/provisioning/dashboards/system/monitor_prometheus.json b/temp-incredible-squaring-avs/grafana/provisioning/dashboards/system/monitor_prometheus.json new file mode 100644 index 0000000..a06c7d0 --- /dev/null +++ b/temp-incredible-squaring-avs/grafana/provisioning/dashboards/system/monitor_prometheus.json @@ -0,0 +1,3412 @@ +{ + "id": null, + "title": "Monitor Prometheus Services", + "tags": [ + "prometheus" + ], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": false, + "sharedCrosshair": true, + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "decimals": 1, + "editable": true, + "error": false, + "format": "s", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 0, + "y": 0 + }, + "hideTimeOverride": true, + "id": 1, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "s", + "postfixFontSize": "80%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "(time() - process_start_time_seconds{instance=\"localhost:9090\",job=\"prometheus\"})", + "interval": "10s", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "timeFrom": "10s", + "timeShift": null, + "title": "Prometheus Uptime", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 6, + "y": 0 + }, + "hideTimeOverride": true, + "id": 5, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(container_memory_usage_bytes{container_label_org_label_schema_group=\"monitoring\"})", + "format": "time_series", + "interval": "10s", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "timeFrom": "10s", + "timeShift": null, + "title": "Memory Usage", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 12, + "y": 0 + }, + "hideTimeOverride": true, + "id": 3, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "prometheus_tsdb_head_chunks", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "timeFrom": "10s", + "timeShift": null, + "title": "In-Memory Chunks", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 18, + "y": 0 + }, + "hideTimeOverride": true, + "id": 2, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "prometheus_tsdb_head_series", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + } + ], + "thresholds": "", + "timeFrom": "10s", + "timeShift": null, + "title": "In-Memory Series", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 3 + }, + "id": 6, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (name) (rate(container_cpu_user_seconds_total{container_label_org_label_schema_group=\"monitoring\"}[1m]) * 100 / scalar(count(node_cpu{mode=\"user\"})))", + "format": "time_series", + "hide": true, + "intervalFactor": 10, + "legendFormat": "{{ name }}", + "refId": "A", + "step": 10 + }, + { + "expr": "sum by (name) (rate(container_cpu_user_seconds_total{container_label_org_label_schema_group=\"monitoring\"}[1m]) * 100 / scalar(count(node_cpu_seconds_total{mode=\"user\"})))", + "format": "time_series", + "intervalFactor": 10, + "legendFormat": "{{ name }}", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Container CPU Usage", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 7, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (name) (container_memory_usage_bytes{container_label_org_label_schema_group=\"monitoring\"})", + "format": "time_series", + "interval": "", + "intervalFactor": 10, + "legendFormat": "{{ name }}", + "metric": "container_memory_usage_bytes", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Container Memory Usage", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 17 + }, + "id": 73, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(ALERTS{alertstate=\"firing\"}) by (alertname)", + "format": "time_series", + "interval": "30s", + "intervalFactor": 1, + "legendFormat": "{{ alertname }}", + "metric": "container_memory_usage_bytes", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Alerts", + "tooltip": { + "msResolution": true, + "shared": false, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 22, + "panels": [], + "repeat": null, + "title": "Prometheus Metrics", + "type": "row" + }, + { + "aliasColors": { + "Max": "#e24d42", + "Open": "#508642" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 25 + }, + "id": 18, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_max_fds{job=\"prometheus\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Max", + "refId": "A" + }, + { + "expr": "process_open_fds{job=\"prometheus\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Open", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "File Descriptors", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Allocated bytes": "#7EB26D", + "Allocated bytes - 1m max": "#BF1B00", + "Allocated bytes - 1m min": "#BF1B00", + "Allocated bytes - 5m max": "#BF1B00", + "Allocated bytes - 5m min": "#BF1B00", + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "RSS": "#447EBC" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": null, + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 25 + }, + "id": 58, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/-/", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_resident_memory_bytes{job=\"prometheus\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "RSS", + "metric": "process_resident_memory_bytes", + "refId": "B", + "step": 10 + }, + { + "expr": "prometheus_local_storage_target_heap_size_bytes{job=\"prometheus\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Target heap size", + "metric": "go_memstats_alloc_bytes", + "refId": "D", + "step": 10 + }, + { + "expr": "go_memstats_next_gc_bytes{job=\"prometheus\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Next GC", + "metric": "go_memstats_next_gc_bytes", + "refId": "C", + "step": 10 + }, + { + "expr": "go_memstats_alloc_bytes{job=\"prometheus\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Allocated", + "metric": "go_memstats_alloc_bytes", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Memory", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Allocated bytes": "#F9BA8F", + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "RSS": "#890F02" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 25 + }, + "id": 60, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(go_memstats_alloc_bytes_total{job=\"prometheus\"}[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Allocated", + "metric": "go_memstats_alloc_bytes", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Allocations", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "Time series": "#70dbed" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 32 + }, + "id": 20, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_tsdb_head_series", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Time series", + "metric": "prometheus_local_storage_memory_series", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head Time series", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 32 + }, + "id": 24, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_tsdb_head_active_appenders", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Head Appenders", + "metric": "prometheus_local_storage_memory_series", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head Active Appenders", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "samples/s": "#e5a8e2" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 32 + }, + "id": 26, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_head_samples_appended_total[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Samples", + "metric": "prometheus_local_storage_ingested_samples_total", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Samples Appended", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": "", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "To persist": "#9AC48A" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 39 + }, + "id": 28, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/Max.*/", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_tsdb_head_chunks", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Chunks", + "metric": "prometheus_local_storage_memory_chunks", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head Chunks", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 39 + }, + "id": 30, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_head_chunks_created_total[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Created", + "metric": "prometheus_local_storage_chunk_ops_total", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head Chunks Created", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "Removed": "#e5ac0e" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 39 + }, + "id": 32, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_head_chunks_removed_total[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Removed", + "metric": "prometheus_local_storage_chunk_ops_total", + "refId": "B", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head Chunks Removed", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max": "#447ebc", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "Min": "#447ebc", + "Now": "#7eb26d" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 46 + }, + "id": 34, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Max", + "fillBelowTo": "Min", + "lines": false + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_tsdb_head_min_time", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Min", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + }, + { + "expr": "time() * 1000", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Now", + "refId": "C" + }, + { + "expr": "prometheus_tsdb_head_max_time", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Max", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "B", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head Time Range", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "dateTimeAsIso", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 46 + }, + "id": 36, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_head_gc_duration_seconds_sum[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "GC Time", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Head GC Time/s", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 46 + }, + "id": 38, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Queue length", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_tsdb_blocks_loaded", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Blocks Loaded", + "metric": "prometheus_local_storage_indexing_batch_sizes_sum", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Blocks Loaded", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Failed Compactions": "#bf1b00", + "Failed Reloads": "#bf1b00", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 53 + }, + "id": 40, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_reloads_total[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Reloads", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "TSDB Reloads", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Failed Compactions": "#bf1b00", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "{instance=\"demo.robustperception.io:9090\",job=\"prometheus\"}": "#bf1b00" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 53 + }, + "id": 44, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_wal_corruptions_total[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "WAL Corruptions", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + }, + { + "expr": "rate(prometheus_tsdb_reloads_failures_total[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Reload Failures", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "B", + "step": 10 + }, + { + "expr": "rate(prometheus_tsdb_head_series_not_found[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Head Series Not Found", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "C", + "step": 10 + }, + { + "expr": "rate(prometheus_tsdb_compactions_failed_total[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Compaction Failures", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "D", + "step": 10 + }, + { + "expr": "rate(prometheus_tsdb_retention_cutoffs_failures_total[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Retention Cutoff Failures", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "E", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "TSDB Problems", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Failed Compactions": "#bf1b00", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 53 + }, + "id": 42, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_wal_fsync_duration_seconds_sum[1m]) / rate(prometheus_tsdb_wal_fsync_duration_seconds_count[1m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Fsync Latency", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + }, + { + "expr": "rate(prometheus_tsdb_wal_truncate_duration_seconds_sum[1m]) / rate(prometheus_tsdb_wal_truncate_duration_seconds_count[1m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Truncate Latency", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "B", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "WAL Latencies", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Failed Compactions": "#bf1b00", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 60 + }, + "id": 46, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_compactions_total[10m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Compactions", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Compactions", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 60 + }, + "id": 48, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_compaction_duration_seconds_sum[10m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Compaction Time", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Compaction Time", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Allocated bytes": "#F9BA8F", + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833", + "RSS": "#890F02" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 60 + }, + "id": 50, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_retention_cutoffs_total[10m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Retention Cutoffs", + "metric": "last", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Retention Cutoffs", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 67 + }, + "id": 56, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_tsdb_compaction_chunk_samples_sum[10m]) / rate(prometheus_tsdb_compaction_chunk_samples_count[10m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Chunk Samples", + "metric": "prometheus_local_storage_series_chunks_persisted_count", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "First Compaction, Avg Chunk Samples", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 67 + }, + "id": 10, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_target_interval_length_seconds_count[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ interval }}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Target Scrapes", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 67 + }, + "id": 11, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_target_interval_length_seconds{quantile!=\"0.01\", quantile!=\"0.05\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{quantile}} ({{interval}})", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Scrape Duration", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 74 + }, + "id": 62, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_http_request_duration_seconds_count[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{handler}}", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "HTTP requests", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "reqps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 74 + }, + "id": 64, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_http_request_duration_seconds_sum[1m]) / rate(prometheus_http_request_duration_seconds_count[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{handler}}", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "HTTP request latency", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 74 + }, + "id": 66, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_http_request_duration_seconds_sum[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{handler}}", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Time spent in HTTP requests", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Time spent in each mode, per second", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 81 + }, + "id": 68, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_engine_query_duration_seconds_sum[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{slice}}", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Query engine timings", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 81 + }, + "id": 70, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_rule_group_iterations_missed_total[1m]) ", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Rule group missed", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "B", + "step": 10 + }, + { + "expr": "rate(prometheus_rule_evaluation_failures_total[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Rule evals failed", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "C", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Rule group evaulation problems", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Chunks": "#1F78C1", + "Chunks to persist": "#508642", + "Max chunks": "#052B51", + "Max to persist": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 81 + }, + "id": 72, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_rule_group_duration_seconds_sum[1m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Rule evaluation duration", + "metric": "prometheus_local_storage_memory_chunkdescs", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Evaluation time of rule groups", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "templating": { + "list": [] + }, + "annotations": { + "list": [] + }, + "refresh": "10s", + "schemaVersion": 12, + "version": 22, + "links": [], + "gnetId": null + } \ No newline at end of file diff --git a/temp-incredible-squaring-avs/grafana/provisioning/datasources/datasource.yml b/temp-incredible-squaring-avs/grafana/provisioning/datasources/datasource.yml new file mode 100644 index 0000000..bf219bb --- /dev/null +++ b/temp-incredible-squaring-avs/grafana/provisioning/datasources/datasource.yml @@ -0,0 +1,12 @@ +apiVersion: 1 + +datasources: + - name: Prometheus + type: prometheus + uid: prometheus + access: proxy + orgId: 1 + url: http://prometheus:9090 + basicAuth: false + isDefault: true + editable: true diff --git a/temp-incredible-squaring-avs/metrics/metrics.go b/temp-incredible-squaring-avs/metrics/metrics.go new file mode 100644 index 0000000..80cd8e8 --- /dev/null +++ b/temp-incredible-squaring-avs/metrics/metrics.go @@ -0,0 +1,52 @@ +package metrics + +import ( + "github.com/Layr-Labs/eigensdk-go/metrics" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +type Metrics interface { + metrics.Metrics + IncNumTasksReceived() + IncNumTasksAcceptedByAggregator() + // This metric would either need to be tracked by the aggregator itself, + // or we would need to write a collector that queries onchain for this info + // AddPercentageStakeSigned(percentage float64) +} + +// AvsMetrics contains instrumented metrics that should be incremented by the avs node using the methods below +type AvsAndEigenMetrics struct { + metrics.Metrics + numTasksReceived prometheus.Counter + // if numSignedTaskResponsesAcceptedByAggregator != numTasksReceived, then there is a bug + numSignedTaskResponsesAcceptedByAggregator prometheus.Counter +} + +const incredibleSquaringNamespace = "incsq" + +func NewAvsAndEigenMetrics(avsName string, eigenMetrics *metrics.EigenMetrics, reg prometheus.Registerer) *AvsAndEigenMetrics { + return &AvsAndEigenMetrics{ + Metrics: eigenMetrics, + numTasksReceived: promauto.With(reg).NewCounter( + prometheus.CounterOpts{ + Namespace: incredibleSquaringNamespace, + Name: "num_tasks_received", + Help: "The number of tasks received by reading from the avs service manager contract", + }), + numSignedTaskResponsesAcceptedByAggregator: promauto.With(reg).NewCounter( + prometheus.CounterOpts{ + Namespace: incredibleSquaringNamespace, + Name: "num_signed_task_responses_accepted_by_aggregator", + Help: "The number of signed task responses accepted by the aggregator", + }), + } +} + +func (m *AvsAndEigenMetrics) IncNumTasksReceived() { + m.numTasksReceived.Inc() +} + +func (m *AvsAndEigenMetrics) IncNumTasksAcceptedByAggregator() { + m.numSignedTaskResponsesAcceptedByAggregator.Inc() +} diff --git a/temp-incredible-squaring-avs/metrics/noopmetrics.go b/temp-incredible-squaring-avs/metrics/noopmetrics.go new file mode 100644 index 0000000..7737a3c --- /dev/null +++ b/temp-incredible-squaring-avs/metrics/noopmetrics.go @@ -0,0 +1,19 @@ +package metrics + +import ( + eigenmetrics "github.com/Layr-Labs/eigensdk-go/metrics" +) + +type NoopMetrics struct { + eigenmetrics.NoopMetrics +} + +func NewNoopMetrics() *NoopMetrics { + return &NoopMetrics{ + NoopMetrics: *eigenmetrics.NewNoopMetrics(), + } +} + +func (m *NoopMetrics) IncNumTasksReceived() {} + +func (m *NoopMetrics) IncNumTasksAcceptedByAggregator() {} diff --git a/temp-incredible-squaring-avs/operator.Dockerfile b/temp-incredible-squaring-avs/operator.Dockerfile new file mode 100644 index 0000000..0e12b9f --- /dev/null +++ b/temp-incredible-squaring-avs/operator.Dockerfile @@ -0,0 +1,17 @@ +FROM golang:1.21 as build + +WORKDIR /usr/src/app + +COPY go.mod go.sum ./ + +RUN go mod download && go mod tidy && go mod verify + +COPY . . + +WORKDIR /usr/src/app/operator/cmd +RUN go build -v -o /usr/local/bin/operator ./... + +FROM debian:latest +COPY --from=build /usr/local/bin/operator /usr/local/bin/operator +ENTRYPOINT [ "operator"] +CMD ["--config=/app/avs_config.yaml"] \ No newline at end of file diff --git a/temp-incredible-squaring-avs/operator/cmd/main.go b/temp-incredible-squaring-avs/operator/cmd/main.go new file mode 100644 index 0000000..d033bfa --- /dev/null +++ b/temp-incredible-squaring-avs/operator/cmd/main.go @@ -0,0 +1,63 @@ +package main + +import ( + "context" + "encoding/json" + "log" + "os" + + "github.com/urfave/cli" + + "github.com/Layr-Labs/incredible-squaring-avs/core/config" + "github.com/Layr-Labs/incredible-squaring-avs/operator" + "github.com/Layr-Labs/incredible-squaring-avs/types" + + sdkutils "github.com/Layr-Labs/eigensdk-go/utils" +) + +func main() { + app := cli.NewApp() + app.Flags = []cli.Flag{config.ConfigFileFlag} + app.Name = "credible-squaring-operator" + app.Usage = "Credible Squaring Operator" + app.Description = "Service that reads numbers onchain, squares, signs, and sends them to the aggregator." + + app.Action = operatorMain + err := app.Run(os.Args) + if err != nil { + log.Fatalln("Application failed. Message:", err) + } +} + +func operatorMain(ctx *cli.Context) error { + + log.Println("Initializing Operator") + configPath := ctx.GlobalString(config.ConfigFileFlag.Name) + nodeConfig := types.NodeConfig{} + err := sdkutils.ReadYamlConfig(configPath, &nodeConfig) + if err != nil { + return err + } + configJson, err := json.MarshalIndent(nodeConfig, "", " ") + if err != nil { + log.Fatalf(err.Error()) + } + log.Println("Config:", string(configJson)) + + log.Println("initializing operator") + operator, err := operator.NewOperatorFromConfig(nodeConfig) + if err != nil { + return err + } + log.Println("initialized operator") + + log.Println("starting operator") + err = operator.Start(context.Background()) + if err != nil { + return err + } + log.Println("started operator") + + return nil + +} diff --git a/temp-incredible-squaring-avs/operator/gen.go b/temp-incredible-squaring-avs/operator/gen.go new file mode 100644 index 0000000..4915e9b --- /dev/null +++ b/temp-incredible-squaring-avs/operator/gen.go @@ -0,0 +1,3 @@ +package operator + +//go:generate mockgen -destination=./mocks/rpc_client.go -package=mocks github.com/Layr-Labs/incredible-squaring-avs/operator AggregatorRpcClienter diff --git a/temp-incredible-squaring-avs/operator/mocks/rpc_client.go b/temp-incredible-squaring-avs/operator/mocks/rpc_client.go new file mode 100644 index 0000000..5cb0ef3 --- /dev/null +++ b/temp-incredible-squaring-avs/operator/mocks/rpc_client.go @@ -0,0 +1,51 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/Layr-Labs/incredible-squaring-avs/operator (interfaces: AggregatorRpcClienter) +// +// Generated by this command: +// +// mockgen -destination=./mocks/rpc_client.go -package=mocks github.com/Layr-Labs/incredible-squaring-avs/operator AggregatorRpcClienter +// +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + aggregator "github.com/Layr-Labs/incredible-squaring-avs/aggregator" + gomock "go.uber.org/mock/gomock" +) + +// MockAggregatorRpcClienter is a mock of AggregatorRpcClienter interface. +type MockAggregatorRpcClienter struct { + ctrl *gomock.Controller + recorder *MockAggregatorRpcClienterMockRecorder +} + +// MockAggregatorRpcClienterMockRecorder is the mock recorder for MockAggregatorRpcClienter. +type MockAggregatorRpcClienterMockRecorder struct { + mock *MockAggregatorRpcClienter +} + +// NewMockAggregatorRpcClienter creates a new mock instance. +func NewMockAggregatorRpcClienter(ctrl *gomock.Controller) *MockAggregatorRpcClienter { + mock := &MockAggregatorRpcClienter{ctrl: ctrl} + mock.recorder = &MockAggregatorRpcClienterMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockAggregatorRpcClienter) EXPECT() *MockAggregatorRpcClienterMockRecorder { + return m.recorder +} + +// SendSignedTaskResponseToAggregator mocks base method. +func (m *MockAggregatorRpcClienter) SendSignedTaskResponseToAggregator(arg0 *aggregator.SignedTaskResponse) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SendSignedTaskResponseToAggregator", arg0) +} + +// SendSignedTaskResponseToAggregator indicates an expected call of SendSignedTaskResponseToAggregator. +func (mr *MockAggregatorRpcClienterMockRecorder) SendSignedTaskResponseToAggregator(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendSignedTaskResponseToAggregator", reflect.TypeOf((*MockAggregatorRpcClienter)(nil).SendSignedTaskResponseToAggregator), arg0) +} diff --git a/temp-incredible-squaring-avs/operator/operator.go b/temp-incredible-squaring-avs/operator/operator.go new file mode 100644 index 0000000..4296f16 --- /dev/null +++ b/temp-incredible-squaring-avs/operator/operator.go @@ -0,0 +1,342 @@ +package operator + +import ( + "context" + "fmt" + "math/big" + "os" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/prometheus/client_golang/prometheus" + + "github.com/Layr-Labs/incredible-squaring-avs/aggregator" + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + "github.com/Layr-Labs/incredible-squaring-avs/core" + "github.com/Layr-Labs/incredible-squaring-avs/core/chainio" + "github.com/Layr-Labs/incredible-squaring-avs/metrics" + "github.com/Layr-Labs/incredible-squaring-avs/types" + + "github.com/Layr-Labs/eigensdk-go/chainio/clients" + sdkelcontracts "github.com/Layr-Labs/eigensdk-go/chainio/clients/elcontracts" + "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" + "github.com/Layr-Labs/eigensdk-go/chainio/clients/wallet" + "github.com/Layr-Labs/eigensdk-go/chainio/txmgr" + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + sdkecdsa "github.com/Layr-Labs/eigensdk-go/crypto/ecdsa" + "github.com/Layr-Labs/eigensdk-go/logging" + sdklogging "github.com/Layr-Labs/eigensdk-go/logging" + sdkmetrics "github.com/Layr-Labs/eigensdk-go/metrics" + "github.com/Layr-Labs/eigensdk-go/metrics/collectors/economic" + rpccalls "github.com/Layr-Labs/eigensdk-go/metrics/collectors/rpc_calls" + "github.com/Layr-Labs/eigensdk-go/nodeapi" + "github.com/Layr-Labs/eigensdk-go/signerv2" + sdktypes "github.com/Layr-Labs/eigensdk-go/types" +) + +const AVS_NAME = "incredible-squaring" +const SEM_VER = "0.0.1" + +type Operator struct { + config types.NodeConfig + logger logging.Logger + ethClient eth.Client + // TODO(samlaf): remove both avsWriter and eigenlayerWrite from operator + // they are only used for registration, so we should make a special registration package + // this way, auditing this operator code makes it obvious that operators don't need to + // write to the chain during the course of their normal operations + // writing to the chain should be done via the cli only + metricsReg *prometheus.Registry + metrics metrics.Metrics + nodeApi *nodeapi.NodeApi + avsWriter *chainio.AvsWriter + avsReader chainio.AvsReaderer + avsSubscriber chainio.AvsSubscriberer + eigenlayerReader sdkelcontracts.ELReader + eigenlayerWriter sdkelcontracts.ELWriter + blsKeypair *bls.KeyPair + operatorId sdktypes.OperatorId + operatorAddr common.Address + // receive new tasks in this chan (typically from listening to onchain event) + newTaskCreatedChan chan *cstaskmanager.ContractIncredibleSquaringTaskManagerNewTaskCreated + // ip address of aggregator + aggregatorServerIpPortAddr string + // rpc client to send signed task responses to aggregator + aggregatorRpcClient AggregatorRpcClienter + // needed when opting in to avs (allow this service manager contract to slash operator) + credibleSquaringServiceManagerAddr common.Address +} + +// TODO(samlaf): config is a mess right now, since the chainio client constructors +// +// take the config in core (which is shared with aggregator and challenger) +func NewOperatorFromConfig(c types.NodeConfig) (*Operator, error) { + var logLevel logging.LogLevel + if c.Production { + logLevel = sdklogging.Production + } else { + logLevel = sdklogging.Development + } + logger, err := sdklogging.NewZapLogger(logLevel) + if err != nil { + return nil, err + } + reg := prometheus.NewRegistry() + eigenMetrics := sdkmetrics.NewEigenMetrics(AVS_NAME, c.EigenMetricsIpPortAddress, reg, logger) + avsAndEigenMetrics := metrics.NewAvsAndEigenMetrics(AVS_NAME, eigenMetrics, reg) + + // Setup Node Api + nodeApi := nodeapi.NewNodeApi(AVS_NAME, SEM_VER, c.NodeApiIpPortAddress, logger) + + var ethRpcClient, ethWsClient eth.Client + if c.EnableMetrics { + rpcCallsCollector := rpccalls.NewCollector(AVS_NAME, reg) + ethRpcClient, err = eth.NewInstrumentedClient(c.EthRpcUrl, rpcCallsCollector) + if err != nil { + logger.Errorf("Cannot create http ethclient", "err", err) + return nil, err + } + ethWsClient, err = eth.NewInstrumentedClient(c.EthWsUrl, rpcCallsCollector) + if err != nil { + logger.Errorf("Cannot create ws ethclient", "err", err) + return nil, err + } + } else { + ethRpcClient, err = eth.NewClient(c.EthRpcUrl) + if err != nil { + logger.Errorf("Cannot create http ethclient", "err", err) + return nil, err + } + ethWsClient, err = eth.NewClient(c.EthWsUrl) + if err != nil { + logger.Errorf("Cannot create ws ethclient", "err", err) + return nil, err + } + } + + blsKeyPassword, ok := os.LookupEnv("OPERATOR_BLS_KEY_PASSWORD") + if !ok { + logger.Warnf("OPERATOR_BLS_KEY_PASSWORD env var not set. using empty string") + } + blsKeyPair, err := bls.ReadPrivateKeyFromFile(c.BlsPrivateKeyStorePath, blsKeyPassword) + if err != nil { + logger.Errorf("Cannot parse bls private key", "err", err) + return nil, err + } + // TODO(samlaf): should we add the chainId to the config instead? + // this way we can prevent creating a signer that signs on mainnet by mistake + // if the config says chainId=5, then we can only create a goerli signer + chainId, err := ethRpcClient.ChainID(context.Background()) + if err != nil { + logger.Error("Cannot get chainId", "err", err) + return nil, err + } + + ecdsaKeyPassword, ok := os.LookupEnv("OPERATOR_ECDSA_KEY_PASSWORD") + if !ok { + logger.Warnf("OPERATOR_ECDSA_KEY_PASSWORD env var not set. using empty string") + } + + signerV2, _, err := signerv2.SignerFromConfig(signerv2.Config{ + KeystorePath: c.EcdsaPrivateKeyStorePath, + Password: ecdsaKeyPassword, + }, chainId) + if err != nil { + panic(err) + } + chainioConfig := clients.BuildAllConfig{ + EthHttpUrl: c.EthRpcUrl, + EthWsUrl: c.EthWsUrl, + RegistryCoordinatorAddr: c.AVSRegistryCoordinatorAddress, + OperatorStateRetrieverAddr: c.OperatorStateRetrieverAddress, + AvsName: AVS_NAME, + PromMetricsIpPortAddress: c.EigenMetricsIpPortAddress, + } + operatorEcdsaPrivateKey, err := sdkecdsa.ReadKey( + c.EcdsaPrivateKeyStorePath, + ecdsaKeyPassword, + ) + if err != nil { + return nil, err + } + sdkClients, err := clients.BuildAll(chainioConfig, operatorEcdsaPrivateKey, logger) + if err != nil { + panic(err) + } + skWallet, err := wallet.NewPrivateKeyWallet(ethRpcClient, signerV2, common.HexToAddress(c.OperatorAddress), logger) + if err != nil { + panic(err) + } + txMgr := txmgr.NewSimpleTxManager(skWallet, ethRpcClient, logger, common.HexToAddress(c.OperatorAddress)) + + avsWriter, err := chainio.BuildAvsWriter( + txMgr, common.HexToAddress(c.AVSRegistryCoordinatorAddress), + common.HexToAddress(c.OperatorStateRetrieverAddress), ethRpcClient, logger, + ) + if err != nil { + logger.Error("Cannot create AvsWriter", "err", err) + return nil, err + } + + avsReader, err := chainio.BuildAvsReader( + common.HexToAddress(c.AVSRegistryCoordinatorAddress), + common.HexToAddress(c.OperatorStateRetrieverAddress), + ethRpcClient, logger) + if err != nil { + logger.Error("Cannot create AvsReader", "err", err) + return nil, err + } + avsSubscriber, err := chainio.BuildAvsSubscriber(common.HexToAddress(c.AVSRegistryCoordinatorAddress), + common.HexToAddress(c.OperatorStateRetrieverAddress), ethWsClient, logger, + ) + if err != nil { + logger.Error("Cannot create AvsSubscriber", "err", err) + return nil, err + } + + // We must register the economic metrics separately because they are exported metrics (from jsonrpc or subgraph calls) + // and not instrumented metrics: see https://prometheus.io/docs/instrumenting/writing_clientlibs/#overall-structure + quorumNames := map[sdktypes.QuorumNum]string{ + 0: "quorum0", + } + economicMetricsCollector := economic.NewCollector( + sdkClients.ElChainReader, sdkClients.AvsRegistryChainReader, + AVS_NAME, logger, common.HexToAddress(c.OperatorAddress), quorumNames) + reg.MustRegister(economicMetricsCollector) + + aggregatorRpcClient, err := NewAggregatorRpcClient(c.AggregatorServerIpPortAddress, logger, avsAndEigenMetrics) + if err != nil { + logger.Error("Cannot create AggregatorRpcClient. Is aggregator running?", "err", err) + return nil, err + } + + operator := &Operator{ + config: c, + logger: logger, + metricsReg: reg, + metrics: avsAndEigenMetrics, + nodeApi: nodeApi, + ethClient: ethRpcClient, + avsWriter: avsWriter, + avsReader: avsReader, + avsSubscriber: avsSubscriber, + eigenlayerReader: sdkClients.ElChainReader, + eigenlayerWriter: sdkClients.ElChainWriter, + blsKeypair: blsKeyPair, + operatorAddr: common.HexToAddress(c.OperatorAddress), + aggregatorServerIpPortAddr: c.AggregatorServerIpPortAddress, + aggregatorRpcClient: aggregatorRpcClient, + newTaskCreatedChan: make(chan *cstaskmanager.ContractIncredibleSquaringTaskManagerNewTaskCreated), + credibleSquaringServiceManagerAddr: common.HexToAddress(c.AVSRegistryCoordinatorAddress), + operatorId: [32]byte{0}, // this is set below + + } + + if c.RegisterOperatorOnStartup { + operator.registerOperatorOnStartup(operatorEcdsaPrivateKey, common.HexToAddress(c.TokenStrategyAddr)) + } + + // OperatorId is set in contract during registration so we get it after registering operator. + operatorId, err := sdkClients.AvsRegistryChainReader.GetOperatorId(&bind.CallOpts{}, operator.operatorAddr) + if err != nil { + logger.Error("Cannot get operator id", "err", err) + return nil, err + } + operator.operatorId = operatorId + logger.Info("Operator info", + "operatorId", operatorId, + "operatorAddr", c.OperatorAddress, + "operatorG1Pubkey", operator.blsKeypair.GetPubKeyG1(), + "operatorG2Pubkey", operator.blsKeypair.GetPubKeyG2(), + ) + + return operator, nil + +} + +func (o *Operator) Start(ctx context.Context) error { + operatorIsRegistered, err := o.avsReader.IsOperatorRegistered(&bind.CallOpts{}, o.operatorAddr) + if err != nil { + o.logger.Error("Error checking if operator is registered", "err", err) + return err + } + if !operatorIsRegistered { + // We bubble the error all the way up instead of using logger.Fatal because logger.Fatal prints a huge stack trace + // that hides the actual error message. This error msg is more explicit and doesn't require showing a stack trace to the user. + return fmt.Errorf("operator is not registered. Registering operator using the operator-cli before starting operator") + } + + o.logger.Infof("Starting operator.") + + if o.config.EnableNodeApi { + o.nodeApi.Start() + } + var metricsErrChan <-chan error + if o.config.EnableMetrics { + metricsErrChan = o.metrics.Start(ctx, o.metricsReg) + } else { + metricsErrChan = make(chan error, 1) + } + + // TODO(samlaf): wrap this call with increase in avs-node-spec metric + sub := o.avsSubscriber.SubscribeToNewTasks(o.newTaskCreatedChan) + for { + select { + case <-ctx.Done(): + return nil + case err := <-metricsErrChan: + // TODO(samlaf); we should also register the service as unhealthy in the node api + // https://eigen.nethermind.io/docs/spec/api/ + o.logger.Fatal("Error in metrics server", "err", err) + case err := <-sub.Err(): + o.logger.Error("Error in websocket subscription", "err", err) + // TODO(samlaf): write unit tests to check if this fixed the issues we were seeing + sub.Unsubscribe() + // TODO(samlaf): wrap this call with increase in avs-node-spec metric + sub = o.avsSubscriber.SubscribeToNewTasks(o.newTaskCreatedChan) + case newTaskCreatedLog := <-o.newTaskCreatedChan: + o.metrics.IncNumTasksReceived() + taskResponse := o.ProcessNewTaskCreatedLog(newTaskCreatedLog) + signedTaskResponse, err := o.SignTaskResponse(taskResponse) + if err != nil { + continue + } + go o.aggregatorRpcClient.SendSignedTaskResponseToAggregator(signedTaskResponse) + } + } +} + +// Takes a NewTaskCreatedLog struct as input and returns a TaskResponseHeader struct. +// The TaskResponseHeader struct is the struct that is signed and sent to the contract as a task response. +func (o *Operator) ProcessNewTaskCreatedLog(newTaskCreatedLog *cstaskmanager.ContractIncredibleSquaringTaskManagerNewTaskCreated) *cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse { + o.logger.Debug("Received new task", "task", newTaskCreatedLog) + o.logger.Info("Received new task", + "numberToBeSquared", newTaskCreatedLog.Task.NumberToBeSquared, + "taskIndex", newTaskCreatedLog.TaskIndex, + "taskCreatedBlock", newTaskCreatedLog.Task.TaskCreatedBlock, + "quorumNumbers", newTaskCreatedLog.Task.QuorumNumbers, + "QuorumThresholdPercentage", newTaskCreatedLog.Task.QuorumThresholdPercentage, + ) + numberSquared := big.NewInt(0).Exp(newTaskCreatedLog.Task.NumberToBeSquared, big.NewInt(2), nil) + taskResponse := &cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse{ + ReferenceTaskIndex: newTaskCreatedLog.TaskIndex, + NumberSquared: numberSquared, + } + return taskResponse +} + +func (o *Operator) SignTaskResponse(taskResponse *cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse) (*aggregator.SignedTaskResponse, error) { + taskResponseHash, err := core.GetTaskResponseDigest(taskResponse) + if err != nil { + o.logger.Error("Error getting task response header hash. skipping task (this is not expected and should be investigated)", "err", err) + return nil, err + } + blsSignature := o.blsKeypair.SignMessage(taskResponseHash) + signedTaskResponse := &aggregator.SignedTaskResponse{ + TaskResponse: *taskResponse, + BlsSignature: *blsSignature, + OperatorId: o.operatorId, + } + o.logger.Debug("Signed task response", "signedTaskResponse", signedTaskResponse) + return signedTaskResponse, nil +} diff --git a/temp-incredible-squaring-avs/operator/operator_test.go b/temp-incredible-squaring-avs/operator/operator_test.go new file mode 100644 index 0000000..8b399d9 --- /dev/null +++ b/temp-incredible-squaring-avs/operator/operator_test.go @@ -0,0 +1,110 @@ +package operator + +import ( + "context" + "fmt" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" + + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + + "github.com/Layr-Labs/incredible-squaring-avs/aggregator" + aggtypes "github.com/Layr-Labs/incredible-squaring-avs/aggregator/types" + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + chainiomocks "github.com/Layr-Labs/incredible-squaring-avs/core/chainio/mocks" + operatormocks "github.com/Layr-Labs/incredible-squaring-avs/operator/mocks" +) + +func TestOperator(t *testing.T) { + operator, err := createMockOperator() + assert.Nil(t, err) + const taskIndex = 1 + + t.Run("ProcessNewTaskCreatedLog", func(t *testing.T) { + var numberToBeSquared = big.NewInt(3) + newTaskCreatedLog := &cstaskmanager.ContractIncredibleSquaringTaskManagerNewTaskCreated{ + TaskIndex: taskIndex, + Task: cstaskmanager.IIncredibleSquaringTaskManagerTask{ + NumberToBeSquared: numberToBeSquared, + TaskCreatedBlock: 1000, + QuorumNumbers: aggtypes.QUORUM_NUMBERS.UnderlyingType(), + QuorumThresholdPercentage: uint32(aggtypes.QUORUM_THRESHOLD_NUMERATOR), + }, + Raw: types.Log{}, + } + got := operator.ProcessNewTaskCreatedLog(newTaskCreatedLog) + numberSquared := big.NewInt(0).Mul(numberToBeSquared, numberToBeSquared) + want := &cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse{ + ReferenceTaskIndex: taskIndex, + NumberSquared: numberSquared, + } + assert.Equal(t, got, want) + }) + + t.Run("Start", func(t *testing.T) { + var numberToBeSquared = big.NewInt(3) + + // new task event + newTaskCreatedEvent := &cstaskmanager.ContractIncredibleSquaringTaskManagerNewTaskCreated{ + TaskIndex: taskIndex, + Task: cstaskmanager.IIncredibleSquaringTaskManagerTask{ + NumberToBeSquared: numberToBeSquared, + TaskCreatedBlock: 1000, + QuorumNumbers: aggtypes.QUORUM_NUMBERS.UnderlyingType(), + QuorumThresholdPercentage: uint32(aggtypes.QUORUM_THRESHOLD_NUMERATOR), + }, + Raw: types.Log{}, + } + fmt.Println("newTaskCreatedEvent", newTaskCreatedEvent) + X, ok := big.NewInt(0).SetString("7926134832136282318561896451042374984489965925674521194255549259381336496956", 10) + assert.True(t, ok) + Y, ok := big.NewInt(0).SetString("15243507701692917330954619280683582177901049846125926696838777109165913318327", 10) + assert.True(t, ok) + + signedTaskResponse := &aggregator.SignedTaskResponse{ + TaskResponse: cstaskmanager.IIncredibleSquaringTaskManagerTaskResponse{ + ReferenceTaskIndex: taskIndex, + NumberSquared: big.NewInt(0).Mul(numberToBeSquared, numberToBeSquared), + }, + BlsSignature: bls.Signature{ + G1Point: bls.NewG1Point(X, Y), + }, + OperatorId: operator.operatorId, + } + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockAggregatorRpcClient := operatormocks.NewMockAggregatorRpcClienter(mockCtrl) + mockAggregatorRpcClient.EXPECT().SendSignedTaskResponseToAggregator(signedTaskResponse) + operator.aggregatorRpcClient = mockAggregatorRpcClient + + mockSubscriber := chainiomocks.NewMockAvsSubscriberer(mockCtrl) + mockSubscriber.EXPECT().SubscribeToNewTasks(operator.newTaskCreatedChan).Return(event.NewSubscription(func(quit <-chan struct{}) error { + // loop forever + <-quit + return nil + })) + operator.avsSubscriber = mockSubscriber + + mockReader := chainiomocks.NewMockAvsReaderer(mockCtrl) + mockReader.EXPECT().IsOperatorRegistered(gomock.Any(), operator.operatorAddr).Return(true, nil) + operator.avsReader = mockReader + + ctx, cancel := context.WithCancel(context.Background()) + go func() { + err := operator.Start(ctx) + assert.Nil(t, err) + }() + operator.newTaskCreatedChan <- newTaskCreatedEvent + time.Sleep(1 * time.Second) + + cancel() + }) + +} diff --git a/temp-incredible-squaring-avs/operator/registration.go b/temp-incredible-squaring-avs/operator/registration.go new file mode 100644 index 0000000..18ef450 --- /dev/null +++ b/temp-incredible-squaring-avs/operator/registration.go @@ -0,0 +1,183 @@ +package operator + +// OUTDATED +// This file contains cli functions for registering an operator with the AVS and printing status +// However, all of this functionality has been moved to the plugin/ package +// we are just waiting for eigenlayer-cli to be open sourced so we can completely get rid of this registration functionality in the operator + +import ( + "context" + "crypto/ecdsa" + "encoding/hex" + "encoding/json" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + eigenSdkTypes "github.com/Layr-Labs/eigensdk-go/types" + + regcoord "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator" +) + +func (o *Operator) registerOperatorOnStartup( + operatorEcdsaPrivateKey *ecdsa.PrivateKey, + mockTokenStrategyAddr common.Address, +) { + err := o.RegisterOperatorWithEigenlayer() + if err != nil { + // This error might only be that the operator was already registered with eigenlayer, so we don't want to fatal + o.logger.Error("Error registering operator with eigenlayer", "err", err) + } else { + o.logger.Infof("Registered operator with eigenlayer") + } + + // TODO(samlaf): shouldn't hardcode number here + amount := big.NewInt(1000) + err = o.DepositIntoStrategy(mockTokenStrategyAddr, amount) + if err != nil { + o.logger.Fatal("Error depositing into strategy", "err", err) + } + o.logger.Infof("Deposited %s into strategy %s", amount, mockTokenStrategyAddr) + + err = o.RegisterOperatorWithAvs(operatorEcdsaPrivateKey) + if err != nil { + o.logger.Fatal("Error registering operator with avs", "err", err) + } + o.logger.Infof("Registered operator with avs") +} + +func (o *Operator) RegisterOperatorWithEigenlayer() error { + op := eigenSdkTypes.Operator{ + Address: o.operatorAddr.String(), + EarningsReceiverAddress: o.operatorAddr.String(), + } + _, err := o.eigenlayerWriter.RegisterAsOperator(context.Background(), op) + if err != nil { + o.logger.Error("Error registering operator with eigenlayer", "err", err) + return err + } + return nil +} + +func (o *Operator) DepositIntoStrategy(strategyAddr common.Address, amount *big.Int) error { + _, tokenAddr, err := o.eigenlayerReader.GetStrategyAndUnderlyingToken(&bind.CallOpts{}, strategyAddr) + if err != nil { + o.logger.Error("Failed to fetch strategy contract", "err", err) + return err + } + contractErc20Mock, err := o.avsReader.GetErc20Mock(context.Background(), tokenAddr) + if err != nil { + o.logger.Error("Failed to fetch ERC20Mock contract", "err", err) + return err + } + txOpts, err := o.avsWriter.TxMgr.GetNoSendTxOpts() + tx, err := contractErc20Mock.Mint(txOpts, o.operatorAddr, amount) + if err != nil { + o.logger.Errorf("Error assembling Mint tx") + return err + } + _, err = o.avsWriter.TxMgr.Send(context.Background(), tx) + if err != nil { + o.logger.Errorf("Error submitting Mint tx") + return err + } + + _, err = o.eigenlayerWriter.DepositERC20IntoStrategy(context.Background(), strategyAddr, amount) + if err != nil { + o.logger.Errorf("Error depositing into strategy", "err", err) + return err + } + return nil +} + +// Registration specific functions +func (o *Operator) RegisterOperatorWithAvs( + operatorEcdsaKeyPair *ecdsa.PrivateKey, +) error { + // hardcode these things for now + quorumNumbers := eigenSdkTypes.QuorumNums{eigenSdkTypes.QuorumNum(0)} + socket := "Not Needed" + operatorToAvsRegistrationSigSalt := [32]byte{123} + curBlockNum, err := o.ethClient.BlockNumber(context.Background()) + if err != nil { + o.logger.Errorf("Unable to get current block number") + return err + } + curBlock, err := o.ethClient.BlockByNumber(context.Background(), big.NewInt(int64(curBlockNum))) + if err != nil { + o.logger.Errorf("Unable to get current block") + return err + } + sigValidForSeconds := int64(1_000_000) + operatorToAvsRegistrationSigExpiry := big.NewInt(int64(curBlock.Time()) + sigValidForSeconds) + _, err = o.avsWriter.RegisterOperatorInQuorumWithAVSRegistryCoordinator( + context.Background(), + operatorEcdsaKeyPair, operatorToAvsRegistrationSigSalt, operatorToAvsRegistrationSigExpiry, + o.blsKeypair, quorumNumbers, socket, + ) + if err != nil { + o.logger.Errorf("Unable to register operator with avs registry coordinator") + return err + } + o.logger.Infof("Registered operator with avs registry coordinator.") + + return nil +} + +// PRINTING STATUS OF OPERATOR: 1 +// operator address: 0xa0ee7a142d267c1f36714e4a8f75612f20a79720 +// dummy token balance: 0 +// delegated shares in dummyTokenStrat: 200 +// operator pubkey hash in AVS pubkey compendium (0 if not registered): 0x4b7b8243d970ff1c90a7c775c008baad825893ec6e806dfa5d3663dc093ed17f +// operator is opted in to eigenlayer: true +// operator is opted in to playgroundAVS (aka can be slashed): true +// operator status in AVS registry: REGISTERED +// +// operatorId: 0x4b7b8243d970ff1c90a7c775c008baad825893ec6e806dfa5d3663dc093ed17f +// middlewareTimesLen (# of stake updates): 0 +// +// operator is frozen: false +type OperatorStatus struct { + EcdsaAddress string + // pubkey compendium related + PubkeysRegistered bool + G1Pubkey string + G2Pubkey string + // avs related + RegisteredWithAvs bool + OperatorId string +} + +func (o *Operator) PrintOperatorStatus() error { + fmt.Println("Printing operator status") + operatorId, err := o.avsReader.GetOperatorId(&bind.CallOpts{}, o.operatorAddr) + if err != nil { + return err + } + pubkeysRegistered := operatorId != [32]byte{} + registeredWithAvs := o.operatorId != [32]byte{} + operatorStatus := OperatorStatus{ + EcdsaAddress: o.operatorAddr.String(), + PubkeysRegistered: pubkeysRegistered, + G1Pubkey: o.blsKeypair.GetPubKeyG1().String(), + G2Pubkey: o.blsKeypair.GetPubKeyG2().String(), + RegisteredWithAvs: registeredWithAvs, + OperatorId: hex.EncodeToString(o.operatorId[:]), + } + operatorStatusJson, err := json.MarshalIndent(operatorStatus, "", " ") + if err != nil { + return err + } + fmt.Println(string(operatorStatusJson)) + return nil +} + +func pubKeyG1ToBN254G1Point(p *bls.G1Point) regcoord.BN254G1Point { + return regcoord.BN254G1Point{ + X: p.X.BigInt(new(big.Int)), + Y: p.Y.BigInt(new(big.Int)), + } +} diff --git a/temp-incredible-squaring-avs/operator/registration_test.go b/temp-incredible-squaring-avs/operator/registration_test.go new file mode 100644 index 0000000..ec5e3af --- /dev/null +++ b/temp-incredible-squaring-avs/operator/registration_test.go @@ -0,0 +1,54 @@ +package operator + +import ( + "testing" + + "github.com/prometheus/client_golang/prometheus" + "github.com/stretchr/testify/assert" + + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + sdklogging "github.com/Layr-Labs/eigensdk-go/logging" + + cstaskmanager "github.com/Layr-Labs/incredible-squaring-avs/contracts/bindings/IncredibleSquaringTaskManager" + "github.com/Layr-Labs/incredible-squaring-avs/metrics" + "github.com/Layr-Labs/incredible-squaring-avs/tests" +) + +const MOCK_OPERATOR_BLS_PRIVATE_KEY = "69" + +// hash of bls_public_key (hardcoded for sk=69) +var MOCK_OPERATOR_ID = [32]byte{207, 73, 226, 221, 104, 100, 123, 41, 192, 3, 9, 119, 90, 83, 233, 159, 231, 151, 245, 96, 150, 48, 144, 27, 102, 253, 39, 101, 1, 26, 135, 173} + +// Name starts with Integration test because we don't want it to run with go test ./... +// since this starts a chain and takes longer to run +// TODO(samlaf): buggy test, fix it +func IntegrationTestOperatorRegistration(t *testing.T) { + anvilCmd := tests.StartAnvilChainAndDeployContracts() + defer anvilCmd.Process.Kill() + operator, err := createMockOperator() + assert.Nil(t, err) + err = operator.RegisterOperatorWithEigenlayer() + assert.Nil(t, err) +} + +func createMockOperator() (*Operator, error) { + logger := sdklogging.NewNoopLogger() + reg := prometheus.NewRegistry() + noopMetrics := metrics.NewNoopMetrics() + + blsPrivateKey, err := bls.NewPrivateKey(MOCK_OPERATOR_BLS_PRIVATE_KEY) + if err != nil { + return nil, err + } + operatorKeypair := bls.NewKeyPair(blsPrivateKey) + + operator := &Operator{ + logger: logger, + blsKeypair: operatorKeypair, + metricsReg: reg, + metrics: noopMetrics, + newTaskCreatedChan: make(chan *cstaskmanager.ContractIncredibleSquaringTaskManagerNewTaskCreated), + operatorId: MOCK_OPERATOR_ID, + } + return operator, nil +} diff --git a/temp-incredible-squaring-avs/operator/rpc_client.go b/temp-incredible-squaring-avs/operator/rpc_client.go new file mode 100644 index 0000000..c8ea373 --- /dev/null +++ b/temp-incredible-squaring-avs/operator/rpc_client.go @@ -0,0 +1,77 @@ +package operator + +import ( + "fmt" + "net/rpc" + "time" + + "github.com/Layr-Labs/incredible-squaring-avs/aggregator" + "github.com/Layr-Labs/incredible-squaring-avs/metrics" + + "github.com/Layr-Labs/eigensdk-go/logging" +) + +type AggregatorRpcClienter interface { + SendSignedTaskResponseToAggregator(signedTaskResponse *aggregator.SignedTaskResponse) +} +type AggregatorRpcClient struct { + rpcClient *rpc.Client + metrics metrics.Metrics + logger logging.Logger + aggregatorIpPortAddr string +} + +func NewAggregatorRpcClient(aggregatorIpPortAddr string, logger logging.Logger, metrics metrics.Metrics) (*AggregatorRpcClient, error) { + return &AggregatorRpcClient{ + // set to nil so that we can create an rpc client even if the aggregator is not running + rpcClient: nil, + metrics: metrics, + logger: logger, + aggregatorIpPortAddr: aggregatorIpPortAddr, + }, nil +} + +func (c *AggregatorRpcClient) dialAggregatorRpcClient() error { + client, err := rpc.DialHTTP("tcp", c.aggregatorIpPortAddr) + if err != nil { + return err + } + c.rpcClient = client + return nil +} + +// SendSignedTaskResponseToAggregator sends a signed task response to the aggregator. +// it is meant to be ran inside a go thread, so doesn't return anything. +// this is because sending the signed task response to the aggregator is time sensitive, +// so there is no point in retrying if it fails for a few times. +// Currently hardcoded to retry sending the signed task response 5 times, waiting 2 seconds in between each attempt. +func (c *AggregatorRpcClient) SendSignedTaskResponseToAggregator(signedTaskResponse *aggregator.SignedTaskResponse) { + if c.rpcClient == nil { + c.logger.Info("rpc client is nil. Dialing aggregator rpc client") + err := c.dialAggregatorRpcClient() + if err != nil { + c.logger.Error("Could not dial aggregator rpc client. Not sending signed task response header to aggregator. Is aggregator running?", "err", err) + return + } + } + // we don't check this bool. It's just needed because rpc.Call requires rpc methods to have a return value + var reply bool + // We try to send the response 5 times to the aggregator, waiting 2 times in between each attempt. + // This is mostly only necessary for local testing, since the aggregator sometimes is not ready to process task responses + // before the operator gets the new task created log from anvil (because blocks are mined instantly) + // the aggregator needs to read some onchain data related to quorums before it can accept operator signed task responses. + c.logger.Info("Sending signed task response header to aggregator", "signedTaskResponse", fmt.Sprintf("%#v", signedTaskResponse)) + for i := 0; i < 5; i++ { + err := c.rpcClient.Call("Aggregator.ProcessSignedTaskResponse", signedTaskResponse, &reply) + if err != nil { + c.logger.Info("Received error from aggregator", "err", err) + } else { + c.logger.Info("Signed task response header accepted by aggregator.", "reply", reply) + c.metrics.IncNumTasksAcceptedByAggregator() + return + } + c.logger.Infof("Retrying in 2 seconds") + time.Sleep(2 * time.Second) + } + c.logger.Errorf("Could not send signed task response to aggregator. Tried 5 times.") +} diff --git a/temp-incredible-squaring-avs/plugin.Dockerfile b/temp-incredible-squaring-avs/plugin.Dockerfile new file mode 100644 index 0000000..207e09e --- /dev/null +++ b/temp-incredible-squaring-avs/plugin.Dockerfile @@ -0,0 +1,15 @@ +FROM golang:1.21 as build + +WORKDIR /usr/src/app + +COPY go.mod go.sum ./ + +RUN go mod download && go mod tidy && go mod verify + +COPY . . + +RUN go build -v -o /usr/local/bin/plugin plugin/cmd/main.go + +FROM debian:latest +COPY --from=build /usr/local/bin/plugin /usr/local/bin/plugin +ENTRYPOINT [ "plugin", "--config=/app/avs_config.yaml" ] \ No newline at end of file diff --git a/temp-incredible-squaring-avs/plugin/cmd/main.go b/temp-incredible-squaring-avs/plugin/cmd/main.go new file mode 100644 index 0000000..b0b7a60 --- /dev/null +++ b/temp-incredible-squaring-avs/plugin/cmd/main.go @@ -0,0 +1,247 @@ +package main + +import ( + "context" + "fmt" + "log" + "math/big" + "os" + "time" + + sdkclients "github.com/Layr-Labs/eigensdk-go/chainio/clients" + "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" + "github.com/Layr-Labs/eigensdk-go/chainio/clients/wallet" + "github.com/Layr-Labs/eigensdk-go/chainio/txmgr" + regcoord "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator" + "github.com/Layr-Labs/eigensdk-go/crypto/bls" + sdkecdsa "github.com/Layr-Labs/eigensdk-go/crypto/ecdsa" + "github.com/Layr-Labs/eigensdk-go/logging" + "github.com/Layr-Labs/eigensdk-go/signerv2" + sdktypes "github.com/Layr-Labs/eigensdk-go/types" + "github.com/Layr-Labs/eigensdk-go/utils" + "github.com/Layr-Labs/incredible-squaring-avs/core/chainio" + "github.com/Layr-Labs/incredible-squaring-avs/types" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/urfave/cli" +) + +var ( + /* Required Flags */ + ConfigFileFlag = cli.StringFlag{ + Name: "config", + Required: true, + Usage: "Load configuration from `FILE`", + EnvVar: "CONFIG", + } + EcdsaKeyPasswordFlag = cli.StringFlag{ + Name: "ecdsa-key-password", + Required: false, + Usage: "Password to decrypt the ecdsa key", + EnvVar: "ECDSA_KEY_PASSWORD", + } + BlsKeyPasswordFlag = cli.StringFlag{ + Name: "bls-key-password", + Required: false, + Usage: "Password to decrypt the bls key", + EnvVar: "BLS_KEY_PASSWORD", + } + OperationFlag = cli.StringFlag{ + Name: "operation-type", + Required: true, + Usage: "Supported operations: opt-in, deposit", + EnvVar: "OPERATION_TYPE", + } + StrategyAddrFlag = cli.StringFlag{ + Name: "strategy-addr", + Required: false, + Usage: "Strategy address for deposit mock tokens, only used for deposit action", + EnvVar: "STRATEGY_ADDR", + } +) + +func main() { + app := cli.NewApp() + app.Flags = []cli.Flag{ + ConfigFileFlag, + EcdsaKeyPasswordFlag, + BlsKeyPasswordFlag, + OperationFlag, + StrategyAddrFlag, + } + app.Name = "credible-squaring-plugin" + app.Usage = "Credible Squaring Plugin" + app.Description = "This is used to run one time operations like avs opt-in/opt-out" + app.Action = plugin + err := app.Run(os.Args) + if err != nil { + log.Fatalln("Application failed.", "Message:", err) + } +} + +func plugin(ctx *cli.Context) { + goCtx := context.Background() + + operationType := ctx.GlobalString(OperationFlag.Name) + configPath := ctx.GlobalString(ConfigFileFlag.Name) + + avsConfig := types.NodeConfig{} + err := utils.ReadYamlConfig(configPath, &avsConfig) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(avsConfig) + + ecdsaKeyPassword := ctx.GlobalString(EcdsaKeyPasswordFlag.Name) + + buildClientConfig := sdkclients.BuildAllConfig{ + EthHttpUrl: avsConfig.EthRpcUrl, + EthWsUrl: avsConfig.EthWsUrl, + RegistryCoordinatorAddr: avsConfig.AVSRegistryCoordinatorAddress, + OperatorStateRetrieverAddr: avsConfig.OperatorStateRetrieverAddress, + AvsName: "incredible-squaring", + PromMetricsIpPortAddress: avsConfig.EigenMetricsIpPortAddress, + } + logger, _ := logging.NewZapLogger(logging.Development) + ethHttpClient, err := eth.NewClient(avsConfig.EthRpcUrl) + if err != nil { + fmt.Println("can't connect to eth client") + fmt.Println(err) + return + } + chainID, err := ethHttpClient.ChainID(goCtx) + if err != nil { + fmt.Println("can't get chain id") + fmt.Println(err) + return + } + signerV2, _, err := signerv2.SignerFromConfig(signerv2.Config{ + KeystorePath: avsConfig.EcdsaPrivateKeyStorePath, + Password: ecdsaKeyPassword, + }, chainID) + if err != nil { + fmt.Println("can't create signer") + fmt.Println(err) + return + } + operatorEcdsaPrivateKey, err := sdkecdsa.ReadKey( + avsConfig.EcdsaPrivateKeyStorePath, + ecdsaKeyPassword, + ) + if err != nil { + fmt.Println(err) + return + } + clients, err := sdkclients.BuildAll(buildClientConfig, operatorEcdsaPrivateKey, logger) + avsReader, err := chainio.BuildAvsReader( + common.HexToAddress(avsConfig.AVSRegistryCoordinatorAddress), + common.HexToAddress(avsConfig.OperatorStateRetrieverAddress), + ethHttpClient, + logger, + ) + if err != nil { + fmt.Println("can't create avs reader") + fmt.Println(err) + return + } + skWallet, err := wallet.NewPrivateKeyWallet(ethHttpClient, signerV2, common.HexToAddress(avsConfig.OperatorAddress), logger) + if err != nil { + fmt.Println("can't create wallet") + fmt.Println(err) + return + } + txMgr := txmgr.NewSimpleTxManager(skWallet, ethHttpClient, logger, common.HexToAddress(avsConfig.OperatorAddress)) + avsWriter, err := chainio.BuildAvsWriter( + txMgr, + common.HexToAddress(avsConfig.AVSRegistryCoordinatorAddress), + common.HexToAddress(avsConfig.OperatorStateRetrieverAddress), + ethHttpClient, + logger, + ) + if err != nil { + fmt.Println("can't create avs reader") + fmt.Println(err) + return + } + + if operationType == "opt-in" { + blsKeyPassword := ctx.GlobalString(BlsKeyPasswordFlag.Name) + + blsKeypair, err := bls.ReadPrivateKeyFromFile(avsConfig.BlsPrivateKeyStorePath, blsKeyPassword) + if err != nil { + fmt.Println(err) + return + } + + // Register with registry coordination + quorumNumbers := sdktypes.QuorumNums{0} + socket := "Not Needed" + sigValidForSeconds := int64(1_000_000) + operatorToAvsRegistrationSigSalt := [32]byte{123} + operatorToAvsRegistrationSigExpiry := big.NewInt(int64(time.Now().Unix()) + sigValidForSeconds) + logger.Infof("Registering with registry coordination with quorum numbers %v and socket %s", quorumNumbers, socket) + r, err := clients.AvsRegistryChainWriter.RegisterOperatorInQuorumWithAVSRegistryCoordinator( + goCtx, + operatorEcdsaPrivateKey, operatorToAvsRegistrationSigSalt, operatorToAvsRegistrationSigExpiry, + blsKeypair, quorumNumbers, socket, + ) + if err != nil { + logger.Errorf("Error assembling CreateNewTask tx") + fmt.Println(err) + return + } + logger.Infof("Registered with registry coordination successfully with tx hash %s", r.TxHash.Hex()) + } else if operationType == "opt-out" { + fmt.Println("Opting out of slashing - unimplemented") + } else if operationType == "deposit" { + starategyAddrString := ctx.GlobalString(StrategyAddrFlag.Name) + if len(starategyAddrString) == 0 { + fmt.Println("Strategy address is required for deposit operation") + return + } + strategyAddr := common.HexToAddress(ctx.GlobalString(StrategyAddrFlag.Name)) + _, tokenAddr, err := clients.ElChainReader.GetStrategyAndUnderlyingToken(&bind.CallOpts{}, strategyAddr) + if err != nil { + logger.Error("Failed to fetch strategy contract", "err", err) + return + } + contractErc20Mock, err := avsReader.GetErc20Mock(context.Background(), tokenAddr) + if err != nil { + logger.Error("Failed to fetch ERC20Mock contract", "err", err) + return + } + txOpts, err := avsWriter.TxMgr.GetNoSendTxOpts() + if err != nil { + logger.Errorf("Error getting tx opts") + return + } + amount := big.NewInt(1000) + tx, err := contractErc20Mock.Mint(txOpts, common.HexToAddress(avsConfig.OperatorAddress), amount) + if err != nil { + logger.Errorf("Error assembling Mint tx") + return + } + _, err = avsWriter.TxMgr.Send(context.Background(), tx) + if err != nil { + logger.Errorf("Error submitting Mint tx") + return + } + + _, err = clients.ElChainWriter.DepositERC20IntoStrategy(context.Background(), strategyAddr, amount) + if err != nil { + logger.Errorf("Error depositing into strategy") + return + } + return + } else { + fmt.Println("Invalid operation type") + } +} + +func pubKeyG1ToBN254G1Point(p *bls.G1Point) regcoord.BN254G1Point { + return regcoord.BN254G1Point{ + X: p.X.BigInt(new(big.Int)), + Y: p.Y.BigInt(new(big.Int)), + } +} diff --git a/temp-incredible-squaring-avs/prometheus/prometheus.yml b/temp-incredible-squaring-avs/prometheus/prometheus.yml new file mode 100644 index 0000000..90625a2 --- /dev/null +++ b/temp-incredible-squaring-avs/prometheus/prometheus.yml @@ -0,0 +1,27 @@ +global: + scrape_interval: 15s + + # Attach these labels to any time series or alerts when communicating with + # external systems (federation, remote storage, Alertmanager). + external_labels: + monitor: "docker-host-alpha" + +# A scrape configuration containing exactly one endpoint to scrape. +scrape_configs: + + - job_name: "prometheus" + scrape_interval: 10s + static_configs: + - targets: ["localhost:9090"] + + - job_name: "incredible-squaring-node" + scrape_interval: 5s + static_configs: + # host.docker.internal might not work on linux + # TODO: do https://stackoverflow.com/a/67158212/4971151 + # - targets: ["host.docker.internal:9090"] + - targets: ["incredible-squaring-operator1:9090"] + labels: + bot: "inc-sq-node" + relabel_configs: + # is this actually useful? We already have the job name diff --git a/temp-incredible-squaring-avs/scripts/deposit-into-mocktoken-strategy.sh b/temp-incredible-squaring-avs/scripts/deposit-into-mocktoken-strategy.sh new file mode 100755 index 0000000..f8910e1 --- /dev/null +++ b/temp-incredible-squaring-avs/scripts/deposit-into-mocktoken-strategy.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +RPC_URL=http://localhost:8545 +PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + +# cd to the directory of this script so that this can be run from anywhere +parent_path=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + pwd -P +) +cd $parent_path/.. + +CHAINID=$(cast chain-id) +DEPLOYMENT_OUTPUT_FILE=./contracts/script/output/${CHAINID}/credible_squaring_avs_deployment_output.json +STRATEGY_ADDRESS=$(jq -r '.addresses.erc20MockStrategy' $DEPLOYMENT_OUTPUT_FILE) + +go run cli/main.go --config config-files/operator.anvil.yaml deposit-into-strategy --strategy-addr ${STRATEGY_ADDRESS} --amount 100 diff --git a/temp-incredible-squaring-avs/tests/anvil/README.md b/temp-incredible-squaring-avs/tests/anvil/README.md new file mode 100644 index 0000000..4878de5 --- /dev/null +++ b/temp-incredible-squaring-avs/tests/anvil/README.md @@ -0,0 +1,21 @@ +# Integration Tests + +We store an anvil state files in this directory, so that we can start an anvil chain with the correct state for integration tests. +``` +anvil --load-state STATE_FILE.json +``` + +## Deployment state files + +The various anvil state files such as `eigenlayer-deployed-anvil-state.json` contain the state of the anvil chain after deploying the contracts. They are created by running the various scripts in this folder + +### Eigenlayer deployment state +It was created by running this [deploy script](https://github.com/Layr-Labs/eigenlayer-contracts/blob/2cb9ed107c6c918b9dfbac94cd71b4ab7c94e8c2/script/testing/M2_Deploy_From_Scratch.s.sol). If you ever need to redeploy a new version of eigenlayer contracts, first start an anvil chain that dumps its state after exiting +``` +anvil --dump-state eigenlayer-deployed-anvil-state.json +``` +Then run the deploy script +``` +forge script script/testing/M2_Deploy_From_Scratch.s.sol --rpc-url http://localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --broadcast --sig "run(string memory configFile)" -- M2_deploy_from_scratch.anvil.config.json +``` +and finally kill the anvil chain with `Ctrl-C`. Make sure to copy the deployment [output file](https://github.com/Layr-Labs/eigenlayer-contracts/blob/master/script/output/M2_from_scratch_deployment_data.json) to [eigenlayer_deployment_output.json](../../contracts/script/output/31337/eigenlayer_deployment_output.json) so that the tests can find the deployed contracts. \ No newline at end of file diff --git a/temp-incredible-squaring-avs/tests/anvil/avs-and-eigenlayer-deployed-anvil-state.json b/temp-incredible-squaring-avs/tests/anvil/avs-and-eigenlayer-deployed-anvil-state.json new file mode 100644 index 0000000..6bbdab1 --- /dev/null +++ b/temp-incredible-squaring-avs/tests/anvil/avs-and-eigenlayer-deployed-anvil-state.json @@ -0,0 +1 @@ +{"accounts":{"0x0000000000000000000000000000000000000000":{"nonce":0,"balance":"0x0","code":"0x","storage":{}},"0x0165878a594ca255338adfa4d48449f69242eb8f":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033","storage":{"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x9a676e781a523b5d0c0e43731313a708cb607508","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0x09635f643e140090a9a8dcd712ed6285858cebef":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122007c3990e071012e67e928be8d71cb1c6b5ed96fee92e98c9e70cc231dee7232064736f6c634300080c0033","storage":{"0x0":"0xe7f1725e7734ce288f8367e1bb143e90bb3f05120001","0x1":"0x0","0x32":"0x7a2088a1bfc9d81c55368ae168c2c02570cb814f","0x64":"0xde0b6b3a7640000","0x65":"0x56bc75e2d63100000","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x322813fd9a801c5507c9de605d63cea4f2ce6c44","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0x0b306bf915c4d645ff596e518faf3f9669b97016":{"nonce":1,"balance":"0x0","code":"0x6080604052600436106101ee5760003560e01c80638da5cb5b1161010d578063c052bd61116100a0578063d1c64cc91161006f578063d1c64cc914610604578063ea4d3c9b14610624578063f2fde38b14610658578063f6848d2414610678578063fabc1cbc146106b357600080fd5b8063c052bd6114610584578063c1de3aef146105a4578063c2c51c40146105c4578063cf756fdf146105e457600080fd5b8063a38406a3116100dc578063a38406a3146104fa578063a6a509be1461051a578063b134427114610530578063beffbb891461056457600080fd5b80638da5cb5b1461046b5780639104c319146104895780639b4e4634146104b15780639ba06275146104c457600080fd5b8063595c6a6711610185578063715018a611610154578063715018a6146103ed57806374cdd7981461040257806384d8106214610436578063886f11951461044b57600080fd5b8063595c6a67146103565780635ac86ab71461036b5780635c975abb146103ab57806360f4062b146103c057600080fd5b8063387b1300116101c1578063387b1300146102b457806339b70e38146102d457806344e71c8014610308578063463db0381461033657600080fd5b80630e81073c146101f357806310d67a2f14610226578063136439dd14610248578063292b7b2b14610268575b600080fd5b3480156101ff57600080fd5b5061021361020e366004612406565b6106d3565b6040519081526020015b60405180910390f35b34801561023257600080fd5b50610246610241366004612432565b610911565b005b34801561025457600080fd5b5061024661026336600461244f565b6109c4565b34801561027457600080fd5b5061029c7f000000000000000000000000610178da211fef7d417bc0e6fed39f05609ad78881565b6040516001600160a01b03909116815260200161021d565b3480156102c057600080fd5b506102466102cf366004612468565b610b03565b3480156102e057600080fd5b5061029c7f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c981565b34801561031457600080fd5b5061031d610ea1565b60405167ffffffffffffffff909116815260200161021d565b34801561034257600080fd5b506102466103513660046124a9565b610eca565b34801561036257600080fd5b50610246611056565b34801561037757600080fd5b5061039b6103863660046124d3565b606654600160ff9092169190911b9081161490565b604051901515815260200161021d565b3480156103b757600080fd5b50606654610213565b3480156103cc57600080fd5b506102136103db366004612432565b609b6020526000908152604090205481565b3480156103f957600080fd5b5061024661111d565b34801561040e57600080fd5b5061029c7f00000000000000000000000000000000219ab540356cbb839cbe05303d7705fa81565b34801561044257600080fd5b5061029c611131565b34801561045757600080fd5b5060655461029c906001600160a01b031681565b34801561047757600080fd5b506033546001600160a01b031661029c565b34801561049557600080fd5b5061029c73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac081565b6102466104bf36600461253f565b61121b565b3480156104d057600080fd5b5061029c6104df366004612432565b6098602052600090815260409020546001600160a01b031681565b34801561050657600080fd5b5061029c610515366004612432565b61130a565b34801561052657600080fd5b5061021360995481565b34801561053c57600080fd5b5061029c7f0000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f81565b34801561057057600080fd5b5061024661057f366004612406565b6113dc565b34801561059057600080fd5b5060975461029c906001600160a01b031681565b3480156105b057600080fd5b506102466105bf366004612432565b6115f3565b3480156105d057600080fd5b506102466105df366004612406565b611604565b3480156105f057600080fd5b506102466105ff3660046125b3565b611a07565b34801561061057600080fd5b5061021361061f3660046124a9565b611b30565b34801561063057600080fd5b5061029c7f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc981565b34801561066457600080fd5b50610246610673366004612432565b611c3b565b34801561068457600080fd5b5061039b610693366004612432565b6001600160a01b0390811660009081526098602052604090205416151590565b3480156106bf57600080fd5b506102466106ce36600461244f565b611cb1565b6000336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc916146107265760405162461bcd60e51b815260040161071d90612604565b60405180910390fd5b6001600160a01b0383166107a25760405162461bcd60e51b815260206004820152603a60248201527f456967656e506f644d616e616765722e6164645368617265733a20706f644f7760448201527f6e65722063616e6e6f74206265207a65726f2061646472657373000000000000606482015260840161071d565b60008212156108105760405162461bcd60e51b815260206004820152603460248201527f456967656e506f644d616e616765722e6164645368617265733a207368617265604482015273732063616e6e6f74206265206e6567617469766560601b606482015260840161071d565b61081e633b9aca0083612678565b156108915760405162461bcd60e51b815260206004820152603d60248201527f456967656e506f644d616e616765722e6164645368617265733a20736861726560448201527f73206d75737420626520612077686f6c65204777656920616d6f756e74000000606482015260840161071d565b6001600160a01b0383166000908152609b6020526040812054906108b584836126a2565b6001600160a01b0386166000818152609b6020526040908190208390555191925090600080516020613231833981519152906108f49087815260200190565b60405180910390a26109068282611e0d565b925050505b92915050565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610964573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098891906126e3565b6001600160a01b0316336001600160a01b0316146109b85760405162461bcd60e51b815260040161071d90612700565b6109c181611e4f565b50565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610a0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a30919061274a565b610a4c5760405162461bcd60e51b815260040161071d9061276c565b60665481811614610ac55760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c6974790000000000000000606482015260840161071d565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc91614610b4b5760405162461bcd60e51b815260040161071d90612604565b6001600160a01b038316610bc55760405162461bcd60e51b8152602060048201526047602482015260008051602061325183398151915260448201527f546f6b656e733a20706f644f776e65722063616e6e6f74206265207a65726f206064820152666164647265737360c81b608482015260a40161071d565b6001600160a01b038216610c425760405162461bcd60e51b815260206004820152604a602482015260008051602061325183398151915260448201527f546f6b656e733a2064657374696e6174696f6e2063616e6e6f74206265207a65606482015269726f206164647265737360b01b608482015260a40161071d565b6000811215610cb15760405162461bcd60e51b8152602060048201526041602482015260008051602061325183398151915260448201527f546f6b656e733a207368617265732063616e6e6f74206265206e6567617469766064820152606560f81b608482015260a40161071d565b610cbf633b9aca0082612678565b15610d335760405162461bcd60e51b815260206004820152604a602482015260008051602061325183398151915260448201527f546f6b656e733a20736861726573206d75737420626520612077686f6c6520476064820152691dd95a48185b5bdd5b9d60b21b608482015260a40161071d565b6001600160a01b0383166000908152609b602052604081205490811215610e26576000610d5f826127b4565b905080831115610dc4576001600160a01b0385166000908152609b6020526040812055610d8c81846127d1565b9250846001600160a01b031660008051602061323183398151915282604051610db791815260200190565b60405180910390a2610e24565b6001600160a01b0385166000908152609b602052604081208054859290610dec9084906126a2565b90915550506040518381526001600160a01b038616906000805160206132318339815191529060200160405180910390a25050505050565b505b6001600160a01b03848116600090815260986020526040908190205490516362483a2160e11b815285831660048201526024810185905291169063c490744290604401600060405180830381600087803b158015610e8357600080fd5b505af1158015610e97573d6000803e3d6000fd5b5050505050505050565b609c5460009067ffffffffffffffff1680610ec55767ffffffffffffffff91505090565b919050565b610ed2611f46565b67ffffffffffffffff8116610f645760405162461bcd60e51b815260206004820152604c60248201527f456967656e506f644d616e616765722e73657444656e6562466f726b54696d6560448201527f7374616d703a2063616e6e6f7420736574206e657744656e6562466f726b546960648201526b06d657374616d7020746f20360a41b608482015260a40161071d565b609c5467ffffffffffffffff16156110005760405162461bcd60e51b815260206004820152605360248201527f456967656e506f644d616e616765722e73657444656e6562466f726b54696d6560448201527f7374616d703a2063616e6e6f74207365742064656e6562466f726b54696d657360648201527274616d70206d6f7265207468616e206f6e636560681b608482015260a40161071d565b609c805467ffffffffffffffff191667ffffffffffffffff83169081179091556040519081527f19200b6fdad58f91b2f496b0c444fc4be3eff74a7e24b07770e04a7137bfd9db9060200160405180910390a150565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa15801561109e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c2919061274a565b6110de5760405162461bcd60e51b815260040161071d9061276c565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b611125611f46565b61112f6000611fa0565b565b6066546000908190600190811614156111885760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b604482015260640161071d565b336000908152609860205260409020546001600160a01b03161561120a5760405162461bcd60e51b815260206004820152603360248201527f456967656e506f644d616e616765722e637265617465506f643a2053656e64656044820152721c88185b1c9958591e481a185cc818481c1bd9606a1b606482015260840161071d565b6000611214611ff2565b9250505090565b606654600090600190811614156112705760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b604482015260640161071d565b336000908152609860205260409020546001600160a01b03168061129957611296611ff2565b90505b6040516326d3918d60e21b81526001600160a01b03821690639b4e46349034906112cf908b908b908b908b908b90600401612811565b6000604051808303818588803b1580156112e857600080fd5b505af11580156112fc573d6000803e3d6000fd5b505050505050505050505050565b6001600160a01b038082166000908152609860205260408120549091168061090b576113d5836001600160a01b031660001b60405180610940016040528061090e815260200161292361090e9139604080516001600160a01b037f000000000000000000000000610178da211fef7d417bc0e6fed39f05609ad788166020820152808201919091526000606082015260800160408051601f19818403018152908290526113ba9291602001612886565b60405160208183030381529060405280519060200120612157565b9392505050565b336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc916146114245760405162461bcd60e51b815260040161071d90612604565b600081121561149b5760405162461bcd60e51b815260206004820152603760248201527f456967656e506f644d616e616765722e72656d6f76655368617265733a20736860448201527f617265732063616e6e6f74206265206e65676174697665000000000000000000606482015260840161071d565b6114a9633b9aca0082612678565b1561151e576040805162461bcd60e51b81526020600482015260248101919091527f456967656e506f644d616e616765722e72656d6f76655368617265733a20736860448201527f61726573206d75737420626520612077686f6c65204777656920616d6f756e74606482015260840161071d565b6001600160a01b0382166000908152609b602052604081205461154290839061289b565b905060008112156115d35760405162461bcd60e51b815260206004820152604f60248201527f456967656e506f644d616e616765722e72656d6f76655368617265733a20636160448201527f6e6e6f7420726573756c7420696e20706f64206f776e657220686176696e672060648201526e6e656761746976652073686172657360881b608482015260a40161071d565b6001600160a01b039092166000908152609b602052604090209190915550565b6115fb611f46565b6109c1816121b3565b6001600160a01b03808316600090815260986020526040902054839116331461167f5760405162461bcd60e51b815260206004820152602760248201527f456967656e506f644d616e616765722e6f6e6c79456967656e506f643a206e6f6044820152661d0818481c1bd960ca1b606482015260840161071d565b600260c95414156116d25760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161071d565b600260c9556001600160a01b03831661176e5760405162461bcd60e51b815260206004820152605260248201527f456967656e506f644d616e616765722e7265636f7264426561636f6e4368616960448201527f6e45544842616c616e63655570646174653a20706f644f776e65722063616e6e6064820152716f74206265207a65726f206164647265737360701b608482015260a40161071d565b61177c633b9aca00836128da565b156118155760405162461bcd60e51b815260206004820152605a60248201527f456967656e506f644d616e616765722e7265636f7264426561636f6e4368616960448201527f6e45544842616c616e63655570646174653a2073686172657344656c7461206d60648201527f75737420626520612077686f6c65204777656920616d6f756e74000000000000608482015260a40161071d565b6001600160a01b0383166000908152609b60205260408120549061183984836126a2565b6001600160a01b0386166000908152609b602052604081208290559091506118618383611e0d565b905080156119c957600081121561192c576001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc91663132d49678773beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06118c0856127b4565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561190f57600080fd5b505af1158015611923573d6000803e3d6000fd5b505050506119c9565b604051631452b9d760e11b81526001600160a01b03878116600483015273beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06024830152604482018390527f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc916906328a573ae90606401600060405180830381600087803b1580156119b057600080fd5b505af11580156119c4573d6000803e3d6000fd5b505050505b856001600160a01b0316600080516020613231833981519152866040516119f291815260200190565b60405180910390a25050600160c95550505050565b600054610100900460ff1615808015611a275750600054600160ff909116105b80611a415750303b158015611a41575060005460ff166001145b611aa45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161071d565b6000805460ff191660011790558015611ac7576000805461ff0019166101001790555b611ad0856121b3565b611ad984611fa0565b611ae383836121fd565b8015611b29576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60975460405163321accf960e11b815267ffffffffffffffff8316600482015260009182916001600160a01b039091169063643599f290602401602060405180830381865afa158015611b87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bab91906128ee565b90508061090b5760405162461bcd60e51b815260206004820152605260248201527f456967656e506f644d616e616765722e676574426c6f636b526f6f744174546960448201527f6d657374616d703a20737461746520726f6f742061742074696d657374616d70606482015271081b9bdd081e595d08199a5b985b1a5e995960721b608482015260a40161071d565b611c43611f46565b6001600160a01b038116611ca85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161071d565b6109c181611fa0565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2891906126e3565b6001600160a01b0316336001600160a01b031614611d585760405162461bcd60e51b815260040161071d90612700565b606654198119606654191614611dd65760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c6974790000000000000000606482015260840161071d565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610af8565b6000808313611e2d5760008213611e265750600061090b565b508061090b565b60008213611e4557611e3e836127b4565b905061090b565b611e3e838361289b565b6001600160a01b038116611edd5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a40161071d565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b0316331461112f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161071d565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060996000815461200390612907565b9091555060408051610940810190915261090e8082526000916120a291839133916129236020830139604080516001600160a01b037f000000000000000000000000610178da211fef7d417bc0e6fed39f05609ad788166020820152808201919091526000606082015260800160408051601f198184030181529082905261208e9291602001612886565b6040516020818303038152906040526122e7565b60405163189acdbd60e31b81523360048201529091506001600160a01b0382169063c4d66de890602401600060405180830381600087803b1580156120e657600080fd5b505af11580156120fa573d6000803e3d6000fd5b50503360008181526098602052604080822080546001600160a01b0319166001600160a01b038816908117909155905192945092507f21c99d0db02213c32fff5b05cf0a718ab5f858802b91498f80d82270289d856a91a3919050565b604080516001600160f81b03196020808301919091526bffffffffffffffffffffffff193060601b16602183015260358201859052605580830185905283518084039091018152607590920190925280519101206000906113d5565b609780546001600160a01b0319166001600160a01b0383169081179091556040517f08f0470754946ccfbb446ff7fd2d6ae6af1bbdae19f85794c0cc5ed5e8ceb4f690600090a250565b6065546001600160a01b031615801561221e57506001600160a01b03821615155b6122a05760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a40161071d565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a26122e382611e4f565b5050565b6000808447101561233a5760405162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e6365000000604482015260640161071d565b82516123885760405162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f604482015260640161071d565b8383516020850187f590506001600160a01b0381166123e95760405162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f7900000000000000604482015260640161071d565b949350505050565b6001600160a01b03811681146109c157600080fd5b6000806040838503121561241957600080fd5b8235612424816123f1565b946020939093013593505050565b60006020828403121561244457600080fd5b81356113d5816123f1565b60006020828403121561246157600080fd5b5035919050565b60008060006060848603121561247d57600080fd5b8335612488816123f1565b92506020840135612498816123f1565b929592945050506040919091013590565b6000602082840312156124bb57600080fd5b813567ffffffffffffffff811681146113d557600080fd5b6000602082840312156124e557600080fd5b813560ff811681146113d557600080fd5b60008083601f84011261250857600080fd5b50813567ffffffffffffffff81111561252057600080fd5b60208301915083602082850101111561253857600080fd5b9250929050565b60008060008060006060868803121561255757600080fd5b853567ffffffffffffffff8082111561256f57600080fd5b61257b89838a016124f6565b9097509550602088013591508082111561259457600080fd5b506125a1888289016124f6565b96999598509660400135949350505050565b600080600080608085870312156125c957600080fd5b84356125d4816123f1565b935060208501356125e4816123f1565b925060408501356125f4816123f1565b9396929550929360600135925050565b602080825260409082018190527f456967656e506f644d616e616765722e6f6e6c7944656c65676174696f6e4d61908201527f6e616765723a206e6f74207468652044656c65676174696f6e4d616e61676572606082015260800190565b634e487b7160e01b600052601260045260246000fd5b60008261268757612687612662565b500690565b634e487b7160e01b600052601160045260246000fd5b600080821280156001600160ff1b03849003851316156126c4576126c461268c565b600160ff1b83900384128116156126dd576126dd61268c565b50500190565b6000602082840312156126f557600080fd5b81516113d5816123f1565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b60006020828403121561275c57600080fd5b815180151581146113d557600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b6000600160ff1b8214156127ca576127ca61268c565b5060000390565b6000828210156127e3576127e361268c565b500390565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6060815260006128256060830187896127e8565b82810360208401526128388186886127e8565b9150508260408301529695505050505050565b6000815160005b8181101561286c5760208185018101518683015201612852565b8181111561287b576000828601525b509290920192915050565b60006123e9612895838661284b565b8461284b565b60008083128015600160ff1b8501841216156128b9576128b961268c565b6001600160ff1b03840183138116156128d4576128d461268c565b50500390565b6000826128e9576128e9612662565b500790565b60006020828403121561290057600080fd5b5051919050565b600060001982141561291b5761291b61268c565b506001019056fe608060405260405161090e38038061090e83398101604081905261002291610460565b61002e82826000610035565b505061058a565b61003e83610100565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100fb576100f9836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e99190610520565b836102a360201b6100291760201c565b505b505050565b610113816102cf60201b6100551760201c565b6101725760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101e6816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d79190610520565b6102cf60201b6100551760201c565b61024b5760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610169565b806102827fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5060001b6102de60201b6100641760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606102c883836040518060600160405280602781526020016108e7602791396102e1565b9392505050565b6001600160a01b03163b151590565b90565b6060600080856001600160a01b0316856040516102fe919061053b565b600060405180830381855af49150503d8060008114610339576040519150601f19603f3d011682016040523d82523d6000602084013e61033e565b606091505b5090925090506103508683838761035a565b9695505050505050565b606083156103c65782516103bf576001600160a01b0385163b6103bf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610169565b50816103d0565b6103d083836103d8565b949350505050565b8151156103e85781518083602001fd5b8060405162461bcd60e51b81526004016101699190610557565b80516001600160a01b038116811461041957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561044f578181015183820152602001610437565b838111156100f95750506000910152565b6000806040838503121561047357600080fd5b61047c83610402565b60208401519092506001600160401b038082111561049957600080fd5b818501915085601f8301126104ad57600080fd5b8151818111156104bf576104bf61041e565b604051601f8201601f19908116603f011681019083821181831017156104e7576104e761041e565b8160405282815288602084870101111561050057600080fd5b610511836020830160208801610434565b80955050505050509250929050565b60006020828403121561053257600080fd5b6102c882610402565b6000825161054d818460208701610434565b9190910192915050565b6020815260008251806020840152610576816040850160208701610434565b601f01601f19169190910160400192915050565b61034e806105996000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610067565b610100565b565b606061004e83836040518060600160405280602781526020016102f260279139610124565b9392505050565b6001600160a01b03163b151590565b90565b600061009a7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fb9190610249565b905090565b3660008037600080366000845af43d6000803e80801561011f573d6000f35b3d6000fd5b6060600080856001600160a01b03168560405161014191906102a2565b600060405180830381855af49150503d806000811461017c576040519150601f19603f3d011682016040523d82523d6000602084013e610181565b606091505b50915091506101928683838761019c565b9695505050505050565b6060831561020d578251610206576001600160a01b0385163b6102065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610217565b610217838361021f565b949350505050565b81511561022f5781518083602001fd5b8060405162461bcd60e51b81526004016101fd91906102be565b60006020828403121561025b57600080fd5b81516001600160a01b038116811461004e57600080fd5b60005b8381101561028d578181015183820152602001610275565b8381111561029c576000848401525b50505050565b600082516102b4818460208701610272565b9190910192915050565b60208152600082518060208401526102dd816040850160208701610272565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220d51e81d3bc5ed20a26aeb05dce7e825c503b2061aa78628027300c8d65b9d89a64736f6c634300080c0033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c65644e2b791dedccd9fb30141b088cabf5c14a8912b52f59375c95c010700b8c6193456967656e506f644d616e616765722e77697468647261775368617265734173a26469706673582212202fb67ee19715abe3d5c61e540dac4e2199f3eb1e931e0d03ff1fd7e29bcee5f764736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x0dcd1bf9a1b36ce34237eeafef220932846bcd82":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106101425760003560e01c80638da5cb5b116100b8578063d79aceab1161007c578063d79aceab146102f8578063df5cf7231461031f578063ec76f44214610346578063f2fde38b14610359578063f698da251461036c578063fabc1cbc1461037457600080fd5b80638da5cb5b1461029b5780639926ee7d146102ac578063a1060c88146102bf578063a364f4da146102d2578063a98fb355146102e557600080fd5b806349075da31161010a57806349075da3146101fa578063595c6a67146102355780635ac86ab71461023d5780635c975abb14610260578063715018a614610268578063886f11951461027057600080fd5b806310d67a2f14610147578063136439dd1461015c5780631794bb3c1461016f57806320606b7014610182578063374823b5146101bc575b600080fd5b61015a6101553660046118ab565b610387565b005b61015a61016a3660046118cf565b610443565b61015a61017d3660046118e8565b610582565b6101a97f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6040519081526020015b60405180910390f35b6101ea6101ca366004611929565b609960209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016101b3565b610228610208366004611955565b609860209081526000928352604080842090915290825290205460ff1681565b6040516101b391906119a4565b61015a6106ac565b6101ea61024b3660046119cc565b606654600160ff9092169190911b9081161490565b6066546101a9565b61015a610773565b606554610283906001600160a01b031681565b6040516001600160a01b0390911681526020016101b3565b6033546001600160a01b0316610283565b61015a6102ba366004611a5f565b610787565b6101a96102cd366004611b46565b610b1a565b61015a6102e03660046118ab565b610bd3565b61015a6102f3366004611b8c565b610d3c565b6101a97fda2c89bafdd34776a2b8bb9c83c82f419e20cc8c67207f70edd58249b92661bd81565b6102837f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc981565b61015a6103543660046118cf565b610d83565b61015a6103673660046118ab565b610e2e565b6101a9610ea4565b61015a6103823660046118cf565b610ee2565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fe9190611bfe565b6001600160a01b0316336001600160a01b0316146104375760405162461bcd60e51b815260040161042e90611c1b565b60405180910390fd5b6104408161103e565b50565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa15801561048b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104af9190611c65565b6104cb5760405162461bcd60e51b815260040161042e90611c87565b606654818116146105445760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c6974790000000000000000606482015260840161042e565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b600054610100900460ff16158080156105a25750600054600160ff909116105b806105bc5750303b1580156105bc575060005460ff166001145b61061f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161042e565b6000805460ff191660011790558015610642576000805461ff0019166101001790555b61064c8383611135565b61065461121f565b609755610660846112b6565b80156106a6576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156106f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107189190611c65565b6107345760405162461bcd60e51b815260040161042e90611c87565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b61077b611308565b61078560006112b6565b565b606654600090600190811614156107dc5760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b604482015260640161042e565b42826040015110156108445760405162461bcd60e51b815260206004820152603e6024820152600080516020611dac83398151915260448201527f56533a206f70657261746f72207369676e617475726520657870697265640000606482015260840161042e565b60013360009081526098602090815260408083206001600160a01b038816845290915290205460ff16600181111561087e5761087e61198e565b14156108e05760405162461bcd60e51b815260206004820152603f6024820152600080516020611dac83398151915260448201527f56533a206f70657261746f7220616c7265616479207265676973746572656400606482015260840161042e565b6001600160a01b038316600090815260996020908152604080832085830151845290915290205460ff16156109645760405162461bcd60e51b81526020600482015260366024820152600080516020611dac8339815191526044820152751594ce881cd85b1d08185b1c9958591e481cdc195b9d60521b606482015260840161042e565b6040516336b87bd760e11b81526001600160a01b0384811660048301527f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc91690636d70f7ae90602401602060405180830381865afa1580156109ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ee9190611c65565b610a645760405162461bcd60e51b815260206004820152604d6024820152600080516020611dac83398151915260448201527f56533a206f70657261746f72206e6f74207265676973746572656420746f204560648201526c1a59d95b93185e595c881e595d609a1b608482015260a40161042e565b6000610a7a843385602001518660400151610b1a565b9050610a8b84828560000151611362565b3360008181526098602090815260408083206001600160a01b0389168085529083528184208054600160ff199182168117909255609985528386208a860151875290945293829020805490931684179092555190917ff0952b1c65271d819d39983d2abb044b9cace59bcc4d4dd389f586ebdcb15b4191610b0c91906119a4565b60405180910390a350505050565b604080517fda2c89bafdd34776a2b8bb9c83c82f419e20cc8c67207f70edd58249b92661bd6020808301919091526001600160a01b0387811683850152861660608301526080820185905260a08083018590528351808403909101815260c0909201909252805191012060009081610b90610ea4565b60405161190160f01b602082015260228101919091526042810183905260620160408051808303601f190181529190528051602090910120979650505050505050565b60665460009060019081161415610c285760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b604482015260640161042e565b60013360009081526098602090815260408083206001600160a01b038716845290915290205460ff166001811115610c6257610c6261198e565b14610cd55760405162461bcd60e51b815260206004820152603f60248201527f4156534469726563746f72792e646572656769737465724f70657261746f724660448201527f726f6d4156533a206f70657261746f72206e6f74207265676973746572656400606482015260840161042e565b3360008181526098602090815260408083206001600160a01b0387168085529252808320805460ff191690555190917ff0952b1c65271d819d39983d2abb044b9cace59bcc4d4dd389f586ebdcb15b4191610d3091906119a4565b60405180910390a35050565b336001600160a01b03167fa89c1dc243d8908a96dd84944bcc97d6bc6ac00dd78e20621576be6a3c9437138383604051610d77929190611ccf565b60405180910390a25050565b33600090815260996020908152604080832084845290915290205460ff1615610e085760405162461bcd60e51b815260206004820152603160248201527f4156534469726563746f72792e63616e63656c53616c743a2063616e6e6f742060448201527018d85b98d95b081cdc195b9d081cd85b1d607a1b606482015260840161042e565b33600090815260996020908152604080832093835292905220805460ff19166001179055565b610e36611308565b6001600160a01b038116610e9b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161042e565b610440816112b6565b60007f0000000000000000000000000000000000000000000000000000000000007a69461415610ed5575060975490565b610edd61121f565b905090565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f599190611bfe565b6001600160a01b0316336001600160a01b031614610f895760405162461bcd60e51b815260040161042e90611c1b565b6066541981196066541916146110075760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c6974790000000000000000606482015260840161042e565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610577565b6001600160a01b0381166110cc5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a40161042e565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b6065546001600160a01b031615801561115657506001600160a01b03821615155b6111d85760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a40161042e565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a261121b8261103e565b5050565b604080518082018252600a81526922b4b3b2b72630bcb2b960b11b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f71b625cfad44bac63b13dba07f2e1d6084ee04b6f8752101ece6126d584ee6ea81840152466060820152306080808301919091528351808303909101815260a0909101909252815191012090565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6033546001600160a01b031633146107855760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161042e565b6001600160a01b0383163b1561148157604051630b135d3f60e11b808252906001600160a01b03851690631626ba7e906113a29086908690600401611cfe565b602060405180830381865afa1580156113bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e39190611d5b565b6001600160e01b0319161461147c5760405162461bcd60e51b815260206004820152605360248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a2045524331323731207369676e6174757265206064820152721d995c9a599a58d85d1a5bdb8819985a5b1959606a1b608482015260a40161042e565b505050565b826001600160a01b03166114958383611521565b6001600160a01b03161461147c5760405162461bcd60e51b815260206004820152604760248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a207369676e6174757265206e6f742066726f6d6064820152661039b4b3b732b960c91b608482015260a40161042e565b60008060006115308585611545565b9150915061153d816115b5565b509392505050565b60008082516041141561157c5760208301516040840151606085015160001a61157087828585611770565b945094505050506115ae565b8251604014156115a6576020830151604084015161159b86838361185d565b9350935050506115ae565b506000905060025b9250929050565b60008160048111156115c9576115c961198e565b14156115d25750565b60018160048111156115e6576115e661198e565b14156116345760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161042e565b60028160048111156116485761164861198e565b14156116965760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161042e565b60038160048111156116aa576116aa61198e565b14156117035760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161042e565b60048160048111156117175761171761198e565b14156104405760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161042e565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156117a75750600090506003611854565b8460ff16601b141580156117bf57508460ff16601c14155b156117d05750600090506004611854565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611824573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661184d57600060019250925050611854565b9150600090505b94509492505050565b6000806001600160ff1b0383168161187a60ff86901c601b611d85565b905061188887828885611770565b935093505050935093915050565b6001600160a01b038116811461044057600080fd5b6000602082840312156118bd57600080fd5b81356118c881611896565b9392505050565b6000602082840312156118e157600080fd5b5035919050565b6000806000606084860312156118fd57600080fd5b833561190881611896565b9250602084013561191881611896565b929592945050506040919091013590565b6000806040838503121561193c57600080fd5b823561194781611896565b946020939093013593505050565b6000806040838503121561196857600080fd5b823561197381611896565b9150602083013561198381611896565b809150509250929050565b634e487b7160e01b600052602160045260246000fd5b60208101600283106119c657634e487b7160e01b600052602160045260246000fd5b91905290565b6000602082840312156119de57600080fd5b813560ff811681146118c857600080fd5b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715611a2857611a286119ef565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611a5757611a576119ef565b604052919050565b60008060408385031215611a7257600080fd5b8235611a7d81611896565b915060208381013567ffffffffffffffff80821115611a9b57600080fd5b9085019060608288031215611aaf57600080fd5b611ab7611a05565b823582811115611ac657600080fd5b8301601f81018913611ad757600080fd5b803583811115611ae957611ae96119ef565b611afb601f8201601f19168701611a2e565b93508084528986828401011115611b1157600080fd5b808683018786013760008682860101525050818152838301358482015260408301356040820152809450505050509250929050565b60008060008060808587031215611b5c57600080fd5b8435611b6781611896565b93506020850135611b7781611896565b93969395505050506040820135916060013590565b60008060208385031215611b9f57600080fd5b823567ffffffffffffffff80821115611bb757600080fd5b818501915085601f830112611bcb57600080fd5b813581811115611bda57600080fd5b866020828501011115611bec57600080fd5b60209290920196919550909350505050565b600060208284031215611c1057600080fd5b81516118c881611896565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215611c7757600080fd5b815180151581146118c857600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b82815260006020604081840152835180604085015260005b81811015611d3257858101830151858201606001528201611d16565b81811115611d44576000606083870101525b50601f01601f191692909201606001949350505050565b600060208284031215611d6d57600080fd5b81516001600160e01b0319811681146118c857600080fd5b60008219821115611da657634e487b7160e01b600052601160045260246000fd5b50019056fe4156534469726563746f72792e72656769737465724f70657261746f72546f41a2646970667358221220b9f71d6d6e6e7c7b30ff4dea984c6d2424f2635bfd916d169a159ef73e00d98e64736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x0e801d84fa97b50751dbf25036d067dcf18858bf":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106100b35760003560e01c8063890262451161007157806389026245146101b3578063a48bb0ac146101d3578063bd29b8cd146101e6578063caa3cd76146101f9578063e2e685801461020f578063f34109221461025557600080fd5b8062bff04d146100b857806312d1d74d146100e157806326d941f2146101155780632ed583e51461012a5780636d14a9871461013d5780638121906f1461017c575b600080fd5b6100cb6100c6366004610ec7565b610268565b6040516100d89190610f43565b60405180910390f35b6100f46100ef366004610fb7565b6103ca565b60408051825163ffffffff16815260209283015192810192909252016100d8565b610128610123366004610fea565b610410565b005b6100f4610138366004611005565b610534565b6101647f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc981565b6040516001600160a01b0390911681526020016100d8565b61018f61018a366004610fea565b6105ba565b60408051825163ffffffff90811682526020938401511692810192909252016100d8565b6101c66101c1366004610fb7565b610601565b6040516100d89190611048565b61018f6101e1366004610fb7565b61076b565b6101286101f4366004610ec7565b6107e2565b610201600081565b6040519081526020016100d8565b61024061021d366004611080565b600160209081526000928352604080842090915290825290205463ffffffff1681565b60405163ffffffff90911681526020016100d8565b610240610263366004610fea565b6108f0565b6060336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc916146102bb5760405162461bcd60e51b81526004016102b2906110aa565b60405180910390fd5b60008267ffffffffffffffff8111156102d6576102d661111d565b6040519080825280602002602001820160405280156102ff578160200160208202803683370190505b50905060005b838110156103bf57600085858381811061032157610321611133565b919091013560f81c60008181526003602052604090205490925090508061035a5760405162461bcd60e51b81526004016102b290611149565b60006103658361090f565b905061037c89846103776001856111b4565b610a08565b8085858151811061038f5761038f611133565b602002602001019063ffffffff16908163ffffffff168152505050505080806103b7906111d9565b915050610305565b5090505b9392505050565b60408051808201909152600080825260208201526103e88383610a92565b60408051808201909152815463ffffffff168152600190910154602082015290505b92915050565b336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc916146104585760405162461bcd60e51b81526004016102b2906110aa565b60ff8116600090815260036020526040902054156104d25760405162461bcd60e51b815260206004820152603160248201527f496e64657852656769737472792e63726561746551756f72756d3a2071756f72604482015270756d20616c72656164792065786973747360781b60648201526084016102b2565b60ff166000908152600360209081526040808320815180830190925263ffffffff438116835282840185815282546001810184559286529390942091519101805492518416600160201b0267ffffffffffffffff199093169190931617179055565b604080518082019091526000808252602082015260ff8416600090815260026020908152604080832063ffffffff8088168552925290912080549091841690811061058157610581611133565b600091825260209182902060408051808201909152600290920201805463ffffffff168252600101549181019190915290509392505050565b60408051808201909152600080825260208201526105d782610aea565b60408051808201909152905463ffffffff8082168352600160201b90910416602082015292915050565b6060600061060f8484610b2c565b905060008163ffffffff1667ffffffffffffffff8111156106325761063261111d565b60405190808252806020026020018201604052801561065b578160200160208202803683370190505b50905060005b8263ffffffff168110156107625761067a868287610c61565b82828151811061068c5761068c611133565b6020026020010181815250506000801b8282815181106106ae576106ae611133565b602002602001015114156107505760405162461bcd60e51b815260206004820152605d60248201527f496e64657852656769737472792e6765744f70657261746f724c69737441744260448201527f6c6f636b4e756d6265723a206f70657261746f7220646f6573206e6f7420657860648201527f6973742061742074686520676976656e20626c6f636b206e756d626572000000608482015260a4016102b2565b8061075a816111d9565b915050610661565b50949350505050565b604080518082019091526000808252602082015260ff83166000908152600360205260409020805463ffffffff84169081106107a9576107a9611133565b60009182526020918290206040805180820190915291015463ffffffff8082168352600160201b90910416918101919091529392505050565b336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc9161461082a5760405162461bcd60e51b81526004016102b2906110aa565b60005b818110156108ea57600083838381811061084957610849611133565b919091013560f81c6000818152600360205260409020549092509050806108825760405162461bcd60e51b81526004016102b290611149565b60ff8216600090815260016020908152604080832089845290915281205463ffffffff16906108b084610d38565b905060006108be8583610d72565b90508089146108d2576108d2818685610a08565b505050505080806108e2906111d9565b91505061082d565b50505050565b60006108fb82610aea565b54600160201b900463ffffffff1692915050565b60008061091b83610aea565b805490915060009061093b90600160201b900463ffffffff1660016111f4565b9050610948848383610d9c565b60ff84166000908152600260205260408120906109666001846111b4565b63ffffffff1681526020810191909152604001600020546103c35760ff841660009081526002602052604081209061099f6001846111b4565b63ffffffff908116825260208083019390935260409182016000908120835180850190945243831684528385018281528154600180820184559284529590922093516002909502909301805463ffffffff19169490921693909317815591519101559392505050565b6000610a148383610a92565b9050610a2283838387610e3c565b60ff83166000818152600160209081526040808320888452825291829020805463ffffffff191663ffffffff871690811790915582519384529083015285917f6ee1e4f4075f3d067176140d34e87874244dd273294c05b2218133e49a2ba6f6910160405180910390a250505050565b60ff8216600090815260026020908152604080832063ffffffff851684529091528120805490610ac360018361121c565b81548110610ad357610ad3611133565b906000526020600020906002020191505092915050565b60ff81166000908152600360205260408120805490610b0a60018361121c565b81548110610b1a57610b1a611133565b90600052602060002001915050919050565b60ff8216600090815260036020526040812054805b8015610bd45760ff85166000908152600360205260408120610b6460018461121c565b81548110610b7457610b74611133565b60009182526020918290206040805180820190915291015463ffffffff808216808452600160201b90920481169383019390935290925090861610610bc15760200151925061040a915050565b5080610bcc81611233565b915050610b41565b5060405162461bcd60e51b815260206004820152605560248201527f496e64657852656769737472792e5f6f70657261746f72436f756e744174426c60448201527f6f636b4e756d6265723a2071756f72756d20646964206e6f742065786973742060648201527430ba1033b4bb32b710313637b1b590373ab6b132b960591b608482015260a4016102b2565b60ff8316600090815260026020908152604080832063ffffffff86168452909152812054805b8015610d2c5760ff8616600090815260026020908152604080832063ffffffff891684529091528120610cbb60018461121c565b81548110610ccb57610ccb611133565b600091825260209182902060408051808201909152600290920201805463ffffffff9081168084526001909201549383019390935290925090861610610d19576020015192506103c3915050565b5080610d2481611233565b915050610c87565b50600095945050505050565b600080610d4483610aea565b8054909150600090610d6590600190600160201b900463ffffffff166111b4565b90506103c3848383610d9c565b600080610d7f8484610a92565b6001810154909150610d948585846000610e3c565b949350505050565b81544363ffffffff90811691161415610dd357815463ffffffff8216600160201b0267ffffffff0000000019909116178255505050565b60ff83166000908152600360209081526040808320815180830190925263ffffffff438116835285811683850190815282546001810184559286529390942091519101805492518416600160201b0267ffffffffffffffff199093169190931617179055505050565b81544363ffffffff90811691161415610e5b57600182018190556108ea565b60ff93909316600090815260026020818152604080842063ffffffff968716855282528084208151808301909252438716825281830197885280546001808201835591865292909420905191909202909101805463ffffffff1916919094161783559251919092015550565b600080600060408486031215610edc57600080fd5b83359250602084013567ffffffffffffffff80821115610efb57600080fd5b818601915086601f830112610f0f57600080fd5b813581811115610f1e57600080fd5b876020828501011115610f3057600080fd5b6020830194508093505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015610f8157835163ffffffff1683529284019291840191600101610f5f565b50909695505050505050565b803560ff81168114610f9e57600080fd5b919050565b803563ffffffff81168114610f9e57600080fd5b60008060408385031215610fca57600080fd5b610fd383610f8d565b9150610fe160208401610fa3565b90509250929050565b600060208284031215610ffc57600080fd5b6103c382610f8d565b60008060006060848603121561101a57600080fd5b61102384610f8d565b925061103160208501610fa3565b915061103f60408501610fa3565b90509250925092565b6020808252825182820181905260009190848201906040850190845b81811015610f8157835183529284019291840191600101611064565b6000806040838503121561109357600080fd5b61109c83610f8d565b946020939093013593505050565b6020808252604d908201527f496e64657852656769737472792e6f6e6c795265676973747279436f6f72646960408201527f6e61746f723a2063616c6c6572206973206e6f7420746865207265676973747260608201526c3c9031b7b7b93234b730ba37b960991b608082015260a00190565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60208082526035908201527f496e64657852656769737472792e72656769737465724f70657261746f723a206040820152741c5d5bdc9d5b48191bd95cc81b9bdd08195e1a5cdd605a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600063ffffffff838116908316818110156111d1576111d161119e565b039392505050565b60006000198214156111ed576111ed61119e565b5060010190565b600063ffffffff8083168185168083038211156112135761121361119e565b01949350505050565b60008282101561122e5761122e61119e565b500390565b6000816112425761124261119e565b50600019019056fea2646970667358221220f795c7f7a356943cad536a2a3b47f30ebf6af737c162c728bb7363c1d04ae71664736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x14dc79964da2c08b23698b3d3cc7ca32193d9955":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x15d34aaf54267db7d7c367839aaf71a00a2c6a65":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x1613beb3b2c4f22ee086b2b38c1476a3ce7f78e8":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122007c3990e071012e67e928be8d71cb1c6b5ed96fee92e98c9e70cc231dee7232064736f6c634300080c0033","storage":{"0x17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec":"0x1","0x295841a49a1089f4b560f91cfbb0133326654dcbb1041861fc5dde96c724a22f":"0x5000000000000000000000000000000000000000000000000","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x4826533b4897376654bb4d4ad88b7fafd0c98528","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x67d269191c92caf3cd7723f116c85e6e9bf55933"}},"0x2279b7a0a67db372996a5fab50d91eaa73d2ebe6":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033","storage":{"0x0":"0x1","0x33":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x97":"0xe7f1725e7734ce288f8367e1bb143e90bb3f0512","0x98":"0x0","0xc9":"0x1","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x959922be3caee4b8cd9a407cc3ac1c251c2007b1","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x322813fd9a801c5507c9de605d63cea4f2ce6c44":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b506004361061018e5760003560e01c80635c975abb116100de578063ab5921e111610097578063df6fadc111610071578063df6fadc114610366578063e3dae51c14610381578063f3e7387514610394578063fabc1cbc146103a757600080fd5b8063ab5921e11461032b578063ce7c2ac214610340578063d9caed121461035357600080fd5b80635c975abb146102c857806361b01b5d146102d05780637a8b2637146102d9578063886f1195146102ec5780638c871019146103055780638f6a62401461031857600080fd5b80633a98ef391161014b578063485cc95511610125578063485cc9551461026b578063553ca5f81461027e578063595c6a67146102915780635ac86ab71461029957600080fd5b80633a98ef391461023857806343fe08b01461024f57806347e7ef241461025857600080fd5b8063019e27291461019357806310d67a2f146101a857806311c70c9d146101bb578063136439dd146101ce5780632495a599146101e157806339b70e3814610211575b600080fd5b6101a66101a13660046117b8565b6103ba565b005b6101a66101b6366004611802565b61049d565b6101a66101c936600461181f565b610550565b6101a66101dc366004611841565b610605565b6032546101f4906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101f47f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c981565b61024160335481565b604051908152602001610208565b61024160645481565b61024161026636600461185a565b610749565b6101a6610279366004611886565b6108ed565b61024161028c366004611802565b6109bb565b6101a66109cf565b6102b86102a73660046118bf565b6001805460ff9092161b9081161490565b6040519015158152602001610208565b600154610241565b61024160655481565b6102416102e7366004611841565b610a9b565b6000546101f4906201000090046001600160a01b031681565b610241610313366004611841565b610ae6565b610241610326366004611802565b610af1565b610333610aff565b6040516102089190611912565b61024161034e366004611802565b610b1f565b6101a6610361366004611945565b610bb4565b60645460655460408051928352602083019190915201610208565b61024161038f366004611841565b610d7d565b6102416103a2366004611841565b610db6565b6101a66103b5366004611841565b610dc1565b600054610100900460ff16158080156103da5750600054600160ff909116105b806103f45750303b1580156103f4575060005460ff166001145b6104195760405162461bcd60e51b815260040161041090611986565b60405180910390fd5b6000805460ff19166001179055801561043c576000805461ff0019166101001790555b6104468585610f1d565b610450838361102a565b8015610496576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051491906119d4565b6001600160a01b0316336001600160a01b0316146105445760405162461bcd60e51b8152600401610410906119f1565b61054d816110bb565b50565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c791906119d4565b6001600160a01b0316336001600160a01b0316146105f75760405162461bcd60e51b8152600401610410906119f1565b6106018282610f1d565b5050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106769190611a3b565b6106925760405162461bcd60e51b815260040161041090611a5d565b6001548181161461070b5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610410565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6001805460009182918116141561079e5760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610410565b336001600160a01b037f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c916146108165760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e616765726044820152606401610410565b61082084846111c0565b60335460006108316103e883611abb565b905060006103e86108406112a2565b61084a9190611abb565b905060006108588783611ad3565b9050806108658489611aea565b61086f9190611b09565b9550856108d55760405162461bcd60e51b815260206004820152602e60248201527f5374726174656779426173652e6465706f7369743a206e65775368617265732060448201526d63616e6e6f74206265207a65726f60901b6064820152608401610410565b6108df8685611abb565b603355505050505092915050565b600054610100900460ff161580801561090d5750600054600160ff909116105b806109275750303b158015610927575060005460ff166001145b6109435760405162461bcd60e51b815260040161041090611986565b6000805460ff191660011790558015610966576000805461ff0019166101001790555b610970838361102a565b80156109b6576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006109c96102e783610b1f565b92915050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610a1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a409190611a3b565b610a5c5760405162461bcd60e51b815260040161041090611a5d565b600019600181905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b6000806103e8603354610aae9190611abb565b905060006103e8610abd6112a2565b610ac79190611abb565b905081610ad48583611aea565b610ade9190611b09565b949350505050565b60006109c982610d7d565b60006109c96103a283610b1f565b60606040518060800160405280604d8152602001611b61604d9139905090565b604051633d3f06c960e11b81526001600160a01b0382811660048301523060248301526000917f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c990911690637a7e0d9290604401602060405180830381865afa158015610b90573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c99190611b2b565b6001805460029081161415610c075760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610410565b336001600160a01b037f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c91614610c7f5760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e616765726044820152606401610410565b610c8a848484611314565b60335480831115610d195760405162461bcd60e51b815260206004820152604d60248201527f5374726174656779426173652e77697468647261773a20616d6f756e7453686160448201527f726573206d757374206265206c657373207468616e206f7220657175616c207460648201526c6f20746f74616c53686172657360981b608482015260a401610410565b6000610d276103e883611abb565b905060006103e8610d366112a2565b610d409190611abb565b9050600082610d4f8784611aea565b610d599190611b09565b9050610d658685611ad3565b603355610d73888883611397565b5050505050505050565b6000806103e8603354610d909190611abb565b905060006103e8610d9f6112a2565b610da99190611abb565b905080610ad48386611aea565b60006109c982610a9b565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3891906119d4565b6001600160a01b0316336001600160a01b031614610e685760405162461bcd60e51b8152600401610410906119f1565b600154198119600154191614610ee65760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610410565b600181905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c9060200161073e565b60645460408051918252602082018490527ff97ed4e083acac67830025ecbc756d8fe847cdbdca4cee3fe1e128e98b54ecb5910160405180910390a160655460408051918252602082018390527f6ab181e0440bfbf4bacdf2e99674735ce6638005490688c5f994f5399353e452910160405180910390a18082111561101f5760405162461bcd60e51b815260206004820152604b60248201527f53747261746567794261736554564c4c696d6974732e5f73657454564c4c696d60448201527f6974733a206d61785065724465706f7369742065786365656473206d6178546f60648201526a74616c4465706f7369747360a81b608482015260a401610410565b606491909155606555565b600054610100900460ff166110955760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610410565b603280546001600160a01b0319166001600160a01b0384161790556106018160006113ab565b6001600160a01b0381166111495760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610410565b600054604080516001600160a01b03620100009093048316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b60645481111561122a5760405162461bcd60e51b815260206004820152602f60248201527f53747261746567794261736554564c4c696d6974733a206d617820706572206460448201526e195c1bdcda5d08195e18d959591959608a1b6064820152608401610410565b6065546112356112a2565b11156112985760405162461bcd60e51b815260206004820152602c60248201527f53747261746567794261736554564c4c696d6974733a206d6178206465706f7360448201526b1a5d1cc8195e18d95959195960a21b6064820152608401610410565b6106018282611497565b6032546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156112eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130f9190611b2b565b905090565b6032546001600160a01b038381169116146109b65760405162461bcd60e51b815260206004820152603b60248201527f5374726174656779426173652e77697468647261773a2043616e206f6e6c792060448201527f77697468647261772074686520737472617465677920746f6b656e00000000006064820152608401610410565b6109b66001600160a01b0383168483611513565b6000546201000090046001600160a01b03161580156113d257506001600160a01b03821615155b6114545760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610410565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2610601826110bb565b6032546001600160a01b038381169116146106015760405162461bcd60e51b815260206004820152603660248201527f5374726174656779426173652e6465706f7369743a2043616e206f6e6c79206460448201527532b837b9b4ba103ab73232b9363cb4b733aa37b5b2b760511b6064820152608401610410565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180516001600160e01b031663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908401526109b6928692916000916115a3918516908490611620565b8051909150156109b657808060200190518101906115c19190611a3b565b6109b65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610410565b606061162f8484600085611639565b90505b9392505050565b60608247101561169a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610410565b6001600160a01b0385163b6116f15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610410565b600080866001600160a01b0316858760405161170d9190611b44565b60006040518083038185875af1925050503d806000811461174a576040519150601f19603f3d011682016040523d82523d6000602084013e61174f565b606091505b509150915061175f82828661176a565b979650505050505050565b60608315611779575081611632565b8251156117895782518084602001fd5b8160405162461bcd60e51b81526004016104109190611912565b6001600160a01b038116811461054d57600080fd5b600080600080608085870312156117ce57600080fd5b843593506020850135925060408501356117e7816117a3565b915060608501356117f7816117a3565b939692955090935050565b60006020828403121561181457600080fd5b8135611632816117a3565b6000806040838503121561183257600080fd5b50508035926020909101359150565b60006020828403121561185357600080fd5b5035919050565b6000806040838503121561186d57600080fd5b8235611878816117a3565b946020939093013593505050565b6000806040838503121561189957600080fd5b82356118a4816117a3565b915060208301356118b4816117a3565b809150509250929050565b6000602082840312156118d157600080fd5b813560ff8116811461163257600080fd5b60005b838110156118fd5781810151838201526020016118e5565b8381111561190c576000848401525b50505050565b60208152600082518060208401526119318160408501602087016118e2565b601f01601f19169190910160400192915050565b60008060006060848603121561195a57600080fd5b8335611965816117a3565b92506020840135611975816117a3565b929592945050506040919091013590565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6000602082840312156119e657600080fd5b8151611632816117a3565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215611a4d57600080fd5b8151801515811461163257600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008219821115611ace57611ace611aa5565b500190565b600082821015611ae557611ae5611aa5565b500390565b6000816000190483118215151615611b0457611b04611aa5565b500290565b600082611b2657634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215611b3d57600080fd5b5051919050565b60008251611b568184602087016118e2565b919091019291505056fe4261736520537472617465677920696d706c656d656e746174696f6e20746f20696e68657269742066726f6d20666f72206d6f726520636f6d706c657820696d706c656d656e746174696f6e73a26469706673582212208ddbf91c8cfff76479472e68dced3c207cb0d0d222e73191eea06f7ba2232d5964736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x36c02da8a0983159322a80ffe9f24b1acff8b570":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80638da5cb5b116100715780638da5cb5b146101735780639926ee7d14610184578063a364f4da14610197578063a98fb355146101aa578063e481af9d146101bd578063f2fde38b146101c557600080fd5b80631b445516146100b957806333cfb7b7146100ce57806338c8ee64146100f75780636b3aa72e1461010a578063715018a61461014457806377ef731d1461014c575b600080fd5b6100cc6100c736600461118e565b6101d8565b005b6100e16100dc366004611218565b610460565b6040516100ee919061123c565b60405180910390f35b6100cc610105366004611218565b610930565b7f0000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f8757075b6040516001600160a01b0390911681526020016100ee565b6100cc6109e9565b61012c7f0000000000000000000000009e545e3c0baab3e08cdfd552c960a1050f37304281565b6033546001600160a01b031661012c565b6100cc61019236600461133e565b6109fd565b6100cc6101a5366004611218565b610a93565b6100cc6101b83660046113e9565b610b5a565b6100e1610bae565b6100cc6101d3366004611218565b610f78565b6101e0610fee565b60005b818110156103db578282828181106101fd576101fd61143a565b905060200281019061020f9190611450565b610220906040810190602001611218565b6001600160a01b03166323b872dd33308686868181106102425761024261143a565b90506020028101906102549190611450565b604080516001600160e01b031960e087901b1681526001600160a01b039485166004820152939092166024840152013560448201526064016020604051808303816000875af11580156102ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102cf9190611480565b508282828181106102e2576102e261143a565b90506020028101906102f49190611450565b610305906040810190602001611218565b6001600160a01b031663095ea7b37f00000000000000000000000000000000000000000000000000000000000000008585858181106103465761034661143a565b90506020028101906103589190611450565b604080516001600160e01b031960e086901b1681526001600160a01b039093166004840152013560248201526044016020604051808303816000875af11580156103a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ca9190611480565b506103d4816114b8565b90506101e3565b50604051630da22a8b60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631b4455169061042a908590859060040161156c565b600060405180830381600087803b15801561044457600080fd5b505af1158015610458573d6000803e3d6000fd5b505050505050565b6040516309aa152760e11b81526001600160a01b0382811660048301526060916000917f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc916906313542a4e90602401602060405180830381865afa1580156104cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f0919061167a565b60405163871ef04960e01b8152600481018290529091506000906001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc9169063871ef04990602401602060405180830381865afa15801561055b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057f9190611693565b90506001600160c01b038116158061061957507f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc96001600160a01b0316639aa1653d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061491906116bc565b60ff16155b1561063557505060408051600081526020810190915292915050565b6000610649826001600160c01b0316611048565b90506000805b825181101561071f577f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f366001600160a01b0316633ca5a5f58483815181106106995761069961143a565b01602001516040516001600160e01b031960e084901b16815260f89190911c6004820152602401602060405180830381865afa1580156106dd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610701919061167a565b61070b90836116df565b915080610717816114b8565b91505061064f565b5060008167ffffffffffffffff81111561073b5761073b611289565b604051908082528060200260200182016040528015610764578160200160208202803683370190505b5090506000805b84518110156109235760008582815181106107885761078861143a565b0160200151604051633ca5a5f560e01b815260f89190911c6004820181905291506000906001600160a01b037f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f361690633ca5a5f590602401602060405180830381865afa1580156107fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610821919061167a565b905060005b8181101561090d576040516356e4026d60e11b815260ff84166004820152602481018290527f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f366001600160a01b03169063adc804da906044016040805180830381865afa15801561089b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf91906116f7565b600001518686815181106108d5576108d561143a565b6001600160a01b0390921660209283029190910190910152846108f7816114b8565b9550508080610905906114b8565b915050610826565b505050808061091b906114b8565b91505061076b565b5090979650505050505050565b336001600160a01b037f0000000000000000000000009e545e3c0baab3e08cdfd552c960a1050f37304216146109e65760405162461bcd60e51b815260206004820152604a60248201527f6f6e6c79496e6372656469626c655371756172696e675461736b4d616e61676560448201527f723a206e6f742066726f6d206372656469626c65207371756172696e6720746160648201526939b59036b0b730b3b2b960b11b608482015260a4015b60405180910390fd5b50565b6109f1610fee565b6109fb600061110b565b565b336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc91614610a455760405162461bcd60e51b81526004016109dd90611756565b604051639926ee7d60e01b81526001600160a01b037f0000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f8757071690639926ee7d9061042a908590859060040161181b565b336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc91614610adb5760405162461bcd60e51b81526004016109dd90611756565b6040516351b27a6d60e11b81526001600160a01b0382811660048301527f0000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707169063a364f4da906024015b600060405180830381600087803b158015610b3f57600080fd5b505af1158015610b53573d6000803e3d6000fd5b5050505050565b610b62610fee565b60405163a98fb35560e01b81526001600160a01b037f0000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707169063a98fb35590610b25908490600401611866565b606060007f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc96001600160a01b0316639aa1653d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3491906116bc565b60ff16905080610c5257505060408051600081526020810190915290565b6000805b82811015610d0757604051633ca5a5f560e01b815260ff821660048201527f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f366001600160a01b031690633ca5a5f590602401602060405180830381865afa158015610cc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce9919061167a565b610cf390836116df565b915080610cff816114b8565b915050610c56565b5060008167ffffffffffffffff811115610d2357610d23611289565b604051908082528060200260200182016040528015610d4c578160200160208202803683370190505b5090506000805b7f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc96001600160a01b0316639aa1653d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610db1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd591906116bc565b60ff16811015610f6e57604051633ca5a5f560e01b815260ff821660048201526000907f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f366001600160a01b031690633ca5a5f590602401602060405180830381865afa158015610e49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6d919061167a565b905060005b81811015610f59576040516356e4026d60e11b815260ff84166004820152602481018290527f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f366001600160a01b03169063adc804da906044016040805180830381865afa158015610ee7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0b91906116f7565b60000151858581518110610f2157610f2161143a565b6001600160a01b039092166020928302919091019091015283610f43816114b8565b9450508080610f51906114b8565b915050610e72565b50508080610f66906114b8565b915050610d53565b5090949350505050565b610f80610fee565b6001600160a01b038116610fe55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109dd565b6109e68161110b565b6033546001600160a01b031633146109fb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109dd565b60606000806110568461115d565b61ffff1667ffffffffffffffff81111561107257611072611289565b6040519080825280601f01601f19166020018201604052801561109c576020820181803683370190505b5090506000805b8251821080156110b4575061010081105b15610f6e576001811b9350858416156110fb578060f81b8383815181106110dd576110dd61143a565b60200101906001600160f81b031916908160001a9053508160010191505b611104816114b8565b90506110a3565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000805b821561118857611172600184611879565b909216918061118081611890565b915050611161565b92915050565b600080602083850312156111a157600080fd5b823567ffffffffffffffff808211156111b957600080fd5b818501915085601f8301126111cd57600080fd5b8135818111156111dc57600080fd5b8660208260051b85010111156111f157600080fd5b60209290920196919550909350505050565b6001600160a01b03811681146109e657600080fd5b60006020828403121561122a57600080fd5b813561123581611203565b9392505050565b6020808252825182820181905260009190848201906040850190845b8181101561127d5783516001600160a01b031683529284019291840191600101611258565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156112c2576112c2611289565b60405290565b600067ffffffffffffffff808411156112e3576112e3611289565b604051601f8501601f19908116603f0116810190828211818310171561130b5761130b611289565b8160405280935085815286868601111561132457600080fd5b858560208301376000602087830101525050509392505050565b6000806040838503121561135157600080fd5b823561135c81611203565b9150602083013567ffffffffffffffff8082111561137957600080fd5b908401906060828703121561138d57600080fd5b61139561129f565b8235828111156113a457600080fd5b83019150601f820187136113b757600080fd5b6113c6878335602085016112c8565b815260208301356020820152604083013560408201528093505050509250929050565b6000602082840312156113fb57600080fd5b813567ffffffffffffffff81111561141257600080fd5b8201601f8101841361142357600080fd5b611432848235602084016112c8565b949350505050565b634e487b7160e01b600052603260045260246000fd5b60008235609e1983360301811261146657600080fd5b9190910192915050565b803561147b81611203565b919050565b60006020828403121561149257600080fd5b8151801515811461123557600080fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156114cc576114cc6114a2565b5060010190565b6bffffffffffffffffffffffff811681146109e657600080fd5b8183526000602080850194508260005b8581101561154d57813561151081611203565b6001600160a01b0316875281830135611528816114d3565b6bffffffffffffffffffffffff168784015260409687019691909101906001016114fd565b509495945050505050565b803563ffffffff8116811461147b57600080fd5b60208082528181018390526000906040808401600586901b8501820187855b8881101561166c57878303603f190184528135368b9003609e190181126115b157600080fd5b8a0160a0813536839003601e190181126115ca57600080fd5b8201803567ffffffffffffffff8111156115e357600080fd5b8060061b36038413156115f557600080fd5b828752611607838801828c85016114ed565b92505050611616888301611470565b6001600160a01b03168886015281870135878601526060611638818401611558565b63ffffffff1690860152608061164f838201611558565b63ffffffff1695019490945250928501929085019060010161158b565b509098975050505050505050565b60006020828403121561168c57600080fd5b5051919050565b6000602082840312156116a557600080fd5b81516001600160c01b038116811461123557600080fd5b6000602082840312156116ce57600080fd5b815160ff8116811461123557600080fd5b600082198211156116f2576116f26114a2565b500190565b60006040828403121561170957600080fd5b6040516040810181811067ffffffffffffffff8211171561172c5761172c611289565b604052825161173a81611203565b8152602083015161174a816114d3565b60208201529392505050565b60208082526052908201527f536572766963654d616e61676572426173652e6f6e6c7952656769737472794360408201527f6f6f7264696e61746f723a2063616c6c6572206973206e6f742074686520726560608201527133b4b9ba393c9031b7b7b93234b730ba37b960711b608082015260a00190565b6000815180845260005b818110156117f4576020818501810151868301820152016117d8565b81811115611806576000602083870101525b50601f01601f19169290920160200192915050565b60018060a01b038316815260406020820152600082516060604084015261184560a08401826117ce565b90506020840151606084015260408401516080840152809150509392505050565b60208152600061123560208301846117ce565b60008282101561188b5761188b6114a2565b500390565b600061ffff808316818114156118a8576118a86114a2565b600101939250505056fea2646970667358221220939ffbc2731160a3acf904aa502ec683052f07166493f46f16b3d34f23164d3664736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x4826533b4897376654bb4d4ad88b7fafd0c98528":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106101155760003560e01c80636d14a987116100a2578063bf79ce5811610071578063bf79ce58146103cc578063d5254a8c146103df578063de29fac0146103ff578063e8bb9ae61461041f578063f4e24fe51461044857600080fd5b80636d14a9871461030a5780637916cea6146103315780637ff81a8714610372578063a3db80e2146103a557600080fd5b80633fb27952116100e95780633fb27952146101df57806347b314e8146101f25780635f61a88414610233578063605747d51461028f57806368bccaac146102dd57600080fd5b8062a1f4cb1461011a57806313542a4e1461015b57806326d941f214610192578063377ed99d146101a7575b600080fd5b610141610128366004611904565b6003602052600090815260409020805460019091015482565b604080519283526020830191909152015b60405180910390f35b610184610169366004611904565b6001600160a01b031660009081526001602052604090205490565b604051908152602001610152565b6101a56101a0366004611937565b61045b565b005b6101ca6101b5366004611937565b60ff1660009081526004602052604090205490565b60405163ffffffff9091168152602001610152565b6101a56101ed3660046119c2565b6105b4565b61021b610200366004611a68565b6000908152600260205260409020546001600160a01b031690565b6040516001600160a01b039091168152602001610152565b610282610241366004611937565b60408051808201909152600080825260208201525060ff16600090815260056020908152604091829020825180840190935280548352600101549082015290565b6040516101529190611a81565b6102a261029d366004611a98565b610672565b60408051825167ffffffffffffffff1916815260208084015163ffffffff908116918301919091529282015190921690820152606001610152565b6102f06102eb366004611ac2565b610705565b60405167ffffffffffffffff199091168152602001610152565b61021b7f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc981565b61034461033f366004611a98565b6108a0565b6040805167ffffffffffffffff19909416845263ffffffff9283166020850152911690820152606001610152565b610385610380366004611904565b6108eb565b604080518351815260209384015193810193909352820152606001610152565b6101416103b3366004611937565b6005602052600090815260409020805460019091015482565b6101846103da366004611b0a565b6109b8565b6103f26103ed366004611b67565b610e0c565b6040516101529190611bdf565b61018461040d366004611904565b60016020526000908152604090205481565b61021b61042d366004611a68565b6002602052600090815260409020546001600160a01b031681565b6101a56104563660046119c2565b611026565b336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc916146104ac5760405162461bcd60e51b81526004016104a390611c29565b60405180910390fd5b60ff81166000908152600460205260409020541561052b5760405162461bcd60e51b815260206004820152603660248201527f424c5341706b52656769737472792e696e697469616c697a6551756f72756d3a6044820152752071756f72756d20616c72656164792065786973747360501b60648201526084016104a3565b60ff166000908152600460209081526040808320815160608101835284815263ffffffff4381168286019081528285018781528454600181018655948852959096209151919092018054955194518316600160e01b026001600160e01b0395909316600160c01b026001600160e01b03199096169190931c179390931791909116919091179055565b336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc916146105fc5760405162461bcd60e51b81526004016104a390611c29565b6000610607836108eb565b50905061061482826110cf565b7f73a2b7fb844724b971802ae9b15db094d4b7192df9d7350e14eb466b9b22eb4e83610655856001600160a01b031660009081526001602052604090205490565b8460405161066593929190611c9d565b60405180910390a1505050565b604080516060810182526000808252602080830182905282840182905260ff8616825260049052919091208054839081106106af576106af611d09565b600091825260209182902060408051606081018252919092015467ffffffffffffffff1981841b16825263ffffffff600160c01b8204811694830194909452600160e01b90049092169082015290505b92915050565b60ff8316600090815260046020526040812080548291908490811061072c5761072c611d09565b600091825260209182902060408051606081018252919092015467ffffffffffffffff1981841b16825263ffffffff600160c01b82048116948301859052600160e01b9091048116928201929092529250851610156107f35760405162461bcd60e51b815260206004820152603e60248201527f424c5341706b52656769737472792e5f76616c696461746541706b486173684160448201527f74426c6f636b4e756d6265723a20696e64657820746f6f20726563656e74000060648201526084016104a3565b604081015163ffffffff1615806108195750806040015163ffffffff168463ffffffff16105b6108975760405162461bcd60e51b815260206004820152604360248201527f424c5341706b52656769737472792e5f76616c696461746541706b486173684160448201527f74426c6f636b4e756d6265723a206e6f74206c61746573742061706b2075706460648201526261746560e81b608482015260a4016104a3565b51949350505050565b600460205281600052604060002081815481106108bc57600080fd5b600091825260209091200154604081901b925063ffffffff600160c01b820481169250600160e01b9091041683565b60408051808201909152600080825260208201526001600160a01b0382166000818152600360209081526040808320815180830183528154815260019182015481850152948452909152812054909190806109ae5760405162461bcd60e51b815260206004820152603e60248201527f424c5341706b52656769737472792e676574526567697374657265645075626b60448201527f65793a206f70657261746f72206973206e6f742072656769737465726564000060648201526084016104a3565b9094909350915050565b6000336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc91614610a025760405162461bcd60e51b81526004016104a390611c29565b6000610a30610a1936869003860160408701611d1f565b805160009081526020918201519091526040902090565b90507fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5811415610ab8576040805162461bcd60e51b8152602060048201526024810191909152600080516020611f3683398151915260448201527f4b65793a2063616e6e6f74207265676973746572207a65726f207075626b657960648201526084016104a3565b6001600160a01b03851660009081526001602052604090205415610b425760405162461bcd60e51b81526020600482015260476024820152600080516020611f3683398151915260448201527f4b65793a206f70657261746f7220616c72656164792072656769737465726564606482015266207075626b657960c81b608482015260a4016104a3565b6000818152600260205260409020546001600160a01b031615610bc65760405162461bcd60e51b81526020600482015260426024820152600080516020611f3683398151915260448201527f4b65793a207075626c6963206b657920616c7265616479207265676973746572606482015261195960f21b608482015260a4016104a3565b604080516000917f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000191610c1f918835916020808b0135928b01359160608c01359160808d019160c08e01918d35918e8201359101611d51565b6040516020818303038152906040528051906020012060001c610c429190611d9c565b9050610cdc610c7b610c6683610c60368a90038a0160408b01611d1f565b9061131a565b610c7536899003890189611d1f565b906113b1565b610c83611445565b610cc5610cb685610c60604080518082018252600080825260209182015281518083019092526001825260029082015290565b610c75368a90038a018a611d1f565b610cd7368a90038a0160808b01611e0e565b611505565b610d775760405162461bcd60e51b815260206004820152606c6024820152600080516020611f3683398151915260448201527f4b65793a2065697468657220746865204731207369676e61747572652069732060648201527f77726f6e672c206f7220473120616e642047322070726976617465206b65792060848201526b0c8de40dcdee840dac2e8c6d60a31b60a482015260c4016104a3565b6001600160a01b03861660008181526003602090815260408083208982018035825560608b013560019283015590835281842087905586845260029092529182902080546001600160a01b0319168417905590517fe3fb6613af2e8930cf85d47fcf6db10192224a64c6cbe8023e0eee1ba382804191610dfb9160808a0190611e6b565b60405180910390a250949350505050565b606060008367ffffffffffffffff811115610e2957610e29611952565b604051908082528060200260200182016040528015610e52578160200160208202803683370190505b50905060005b8481101561101d576000868683818110610e7457610e74611d09565b919091013560f81c6000818152600460205260409020549092509050801580610ed7575060ff821660009081526004602052604081208054909190610ebb57610ebb611d09565b600091825260209091200154600160c01b900463ffffffff1686105b15610f645760405162461bcd60e51b815260206004820152605160248201527f424c5341706b52656769737472792e67657441706b496e64696365734174426c60448201527f6f636b4e756d6265723a20626c6f636b4e756d626572206973206265666f7265606482015270207468652066697273742075706461746560781b608482015260a4016104a3565b805b80156110075760ff831660009081526004602052604090208790610f8b600184611eb5565b81548110610f9b57610f9b611d09565b600091825260209091200154600160c01b900463ffffffff1611610ff557610fc4600182611eb5565b858581518110610fd657610fd6611d09565b602002602001019063ffffffff16908163ffffffff1681525050611007565b80610fff81611ecc565b915050610f66565b505050808061101590611ee3565b915050610e58565b50949350505050565b336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc9161461106e5760405162461bcd60e51b81526004016104a390611c29565b6000611079836108eb565b50905061108e8261108983611772565b6110cf565b7ff843ecd53a563675e62107be1494fdde4a3d49aeedaf8d88c616d85346e3500e83610655856001600160a01b031660009081526001602052604090205490565b604080518082019091526000808252602082015260005b835181101561131457600084828151811061110357611103611d09565b0160209081015160f81c60008181526004909252604090912054909150806111935760405162461bcd60e51b815260206004820152603d60248201527f424c5341706b52656769737472792e5f70726f6365737351756f72756d41706b60448201527f5570646174653a2071756f72756d20646f6573206e6f7420657869737400000060648201526084016104a3565b60ff821660009081526005602090815260409182902082518084019093528054835260010154908201526111c790866113b1565b60ff831660008181526005602090815260408083208551808255868401805160019384015590855251835281842094845260049092528220939750919290916112109085611eb5565b8154811061122057611220611d09565b600091825260209091200180549091504363ffffffff908116600160c01b9092041614156112615780546001600160c01b031916604083901c1781556112fd565b805463ffffffff438116600160e01b8181026001600160e01b0394851617855560ff88166000908152600460209081526040808320815160608101835267ffffffffffffffff198b16815280840196875280830185815282546001810184559286529390942093519301805495519251871690940291909516600160c01b026001600160e01b0319949094169190941c17919091179092161790555b50505050808061130c90611ee3565b9150506110e6565b50505050565b6040805180820190915260008082526020820152611336611831565b835181526020808501519082015260408082018490526000908360608460076107d05a03fa90508080156113695761136b565bfe5b50806113a95760405162461bcd60e51b815260206004820152600d60248201526c1958cb5b5d5b0b59985a5b1959609a1b60448201526064016104a3565b505092915050565b60408051808201909152600080825260208201526113cd61184f565b835181526020808501518183015283516040808401919091529084015160608301526000908360808460066107d05a03fa90508080156113695750806113a95760405162461bcd60e51b815260206004820152600d60248201526c1958cb5859190b59985a5b1959609a1b60448201526064016104a3565b61144d61186d565b50604080516080810182527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c28183019081527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6060830152815281518083019092527f275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec82527f1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d60208381019190915281019190915290565b604080518082018252858152602080820185905282518084019093528583528201839052600091611534611892565b60005b60028110156116f957600061154d826006611efe565b905084826002811061156157611561611d09565b60200201515183611573836000611f1d565b600c811061158357611583611d09565b602002015284826002811061159a5761159a611d09565b602002015160200151838260016115b19190611f1d565b600c81106115c1576115c1611d09565b60200201528382600281106115d8576115d8611d09565b60200201515151836115eb836002611f1d565b600c81106115fb576115fb611d09565b602002015283826002811061161257611612611d09565b602002015151600160200201518361162b836003611f1d565b600c811061163b5761163b611d09565b602002015283826002811061165257611652611d09565b60200201516020015160006002811061166d5761166d611d09565b60200201518361167e836004611f1d565b600c811061168e5761168e611d09565b60200201528382600281106116a5576116a5611d09565b6020020151602001516001600281106116c0576116c0611d09565b6020020151836116d1836005611f1d565b600c81106116e1576116e1611d09565b602002015250806116f181611ee3565b915050611537565b506117026118b1565b60006020826101808560086107d05a03fa90508080156113695750806117625760405162461bcd60e51b81526020600482015260156024820152741c185a5c9a5b99cb5bdc18dbd9194b59985a5b1959605a1b60448201526064016104a3565b5051151598975050505050505050565b6040805180820190915260008082526020820152815115801561179757506020820151155b156117b5575050604080518082019091526000808252602082015290565b6040518060400160405280836000015181526020017f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4784602001516117fa9190611d9c565b611824907f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47611eb5565b905292915050565b919050565b60405180606001604052806003906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b60405180604001604052806118806118cf565b815260200161188d6118cf565b905290565b604051806101800160405280600c906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b60405180604001604052806002906020820280368337509192915050565b80356001600160a01b038116811461182c57600080fd5b60006020828403121561191657600080fd5b61191f826118ed565b9392505050565b803560ff8116811461182c57600080fd5b60006020828403121561194957600080fd5b61191f82611926565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561198b5761198b611952565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156119ba576119ba611952565b604052919050565b600080604083850312156119d557600080fd5b6119de836118ed565b915060208084013567ffffffffffffffff808211156119fc57600080fd5b818601915086601f830112611a1057600080fd5b813581811115611a2257611a22611952565b611a34601f8201601f19168501611991565b91508082528784828501011115611a4a57600080fd5b80848401858401376000848284010152508093505050509250929050565b600060208284031215611a7a57600080fd5b5035919050565b8151815260208083015190820152604081016106ff565b60008060408385031215611aab57600080fd5b611ab483611926565b946020939093013593505050565b600080600060608486031215611ad757600080fd5b611ae084611926565b9250602084013563ffffffff81168114611af957600080fd5b929592945050506040919091013590565b6000806000838503610160811215611b2157600080fd5b611b2a856118ed565b9350610100601f1982011215611b3f57600080fd5b602085019250604061011f1982011215611b5857600080fd5b50610120840190509250925092565b600080600060408486031215611b7c57600080fd5b833567ffffffffffffffff80821115611b9457600080fd5b818601915086601f830112611ba857600080fd5b813581811115611bb757600080fd5b876020828501011115611bc957600080fd5b6020928301989097509590910135949350505050565b6020808252825182820181905260009190848201906040850190845b81811015611c1d57835163ffffffff1683529284019291840191600101611bfb565b50909695505050505050565b6020808252604e908201527f424c5341706b52656769737472792e6f6e6c795265676973747279436f6f726460408201527f696e61746f723a2063616c6c6572206973206e6f74207468652072656769737460608201526d393c9031b7b7b93234b730ba37b960911b608082015260a00190565b60018060a01b038416815260006020848184015260606040840152835180606085015260005b81811015611cdf57858101830151858201608001528201611cc3565b81811115611cf1576000608083870101525b50601f01601f19169290920160800195945050505050565b634e487b7160e01b600052603260045260246000fd5b600060408284031215611d3157600080fd5b611d39611968565b82358152602083013560208201528091505092915050565b8881528760208201528660408201528560608201526040856080830137600060c082016000815260408682375050610100810192909252610120820152610140019695505050505050565b600082611db957634e487b7160e01b600052601260045260246000fd5b500690565b600082601f830112611dcf57600080fd5b611dd7611968565b806040840185811115611de957600080fd5b845b81811015611e03578035845260209384019301611deb565b509095945050505050565b600060808284031215611e2057600080fd5b6040516040810181811067ffffffffffffffff82111715611e4357611e43611952565b604052611e508484611dbe565b8152611e5f8460408501611dbe565b60208201529392505050565b823581526020808401359082015260c081016040838184013760808201600081526040808501823750600081529392505050565b634e487b7160e01b600052601160045260246000fd5b600082821015611ec757611ec7611e9f565b500390565b600081611edb57611edb611e9f565b506000190190565b6000600019821415611ef757611ef7611e9f565b5060010190565b6000816000190483118215151615611f1857611f18611e9f565b500290565b60008219821115611f3057611f30611e9f565b50019056fe424c5341706b52656769737472792e7265676973746572424c535075626c6963a2646970667358221220de265fd453dc93f627225957b8d623fbf574dbf76efc77f2c916809d041b231464736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x4c5859f0f772848b2d91f1d83e2fe57935348029":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b506004361061021c5760003560e01c80636b532e9e116101255780638da5cb5b116100ad578063f2fde38b1161007c578063f2fde38b14610587578063f5c9899d1461059a578063f63c5bab146105c0578063f8c8765e146105c8578063fabc1cbc146105db57600080fd5b80638da5cb5b14610521578063b98d090814610532578063cefdc1d41461053f578063df5cf7231461056057600080fd5b8063715018a6116100f4578063715018a6146104d557806372d18e8d146104dd5780637afa1eed146104eb578063886f1195146104fe5780638b00ce7c1461051157600080fd5b80636b532e9e146104675780636b92787e1461047a5780636d14a9871461048d5780636efb4636146104b457600080fd5b80634f739f74116101a85780635c155662116101775780635c155662146103ce5780635c975abb146103ee5780635decc3f5146103f65780635df4594614610419578063683048351461044057600080fd5b80634f739f7414610360578063595c6a67146103805780635ac86ab7146103885780635baec9a0146103bb57600080fd5b8063245a7bfc116101ef578063245a7bfc146102b45780632cb223d5146102df5780632d89f6fc1461030d5780633563b0d11461032d578063416c7e5e1461034d57600080fd5b806310d67a2f14610221578063136439dd14610236578063171f1d5b146102495780631ad4318914610278575b600080fd5b61023461022f3660046146c1565b6105ee565b005b6102346102443660046146de565b6106aa565b61025c61025736600461485c565b6107e9565b6040805192151583529015156020830152015b60405180910390f35b61029f7f000000000000000000000000000000000000000000000000000000000000001e81565b60405163ffffffff909116815260200161026f565b60cd546102c7906001600160a01b031681565b6040516001600160a01b03909116815260200161026f565b6102ff6102ed3660046148ca565b60cb6020526000908152604090205481565b60405190815260200161026f565b6102ff61031b3660046148ca565b60ca6020526000908152604090205481565b61034061033b3660046148e7565b610973565b60405161026f9190614a42565b61023461035b366004614a6a565b610e09565b61037361036e366004614acf565b610f7e565b60405161026f9190614bd3565b6102346116a4565b6103ab610396366004614c9d565b606654600160ff9092169190911b9081161490565b604051901515815260200161026f565b6102346103c9366004614f88565b61176b565b6103e16103dc366004614ffc565b611bea565b60405161026f91906150a8565b6066546102ff565b6103ab6104043660046148ca565b60cc6020526000908152604090205460ff1681565b6102c77f0000000000000000000000001613beb3b2c4f22ee086b2b38c1476a3ce7f78e881565b6102c77f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f3681565b6102346104753660046150ec565b611db2565b610234610488366004615172565b612384565b6102c77f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc981565b6104c76104c23660046151cd565b612525565b60405161026f92919061528d565b61023461341d565b60c95463ffffffff1661029f565b60ce546102c7906001600160a01b031681565b6065546102c7906001600160a01b031681565b60c95461029f9063ffffffff1681565b6033546001600160a01b03166102c7565b6097546103ab9060ff1681565b61055261054d3660046152d6565b613431565b60405161026f929190615318565b6102c77f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc981565b6102346105953660046146c1565b6135c3565b7f000000000000000000000000000000000000000000000000000000000000001e61029f565b61029f606481565b6102346105d6366004615339565b613639565b6102346105e93660046146de565b61378a565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610641573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106659190615395565b6001600160a01b0316336001600160a01b03161461069e5760405162461bcd60e51b8152600401610695906153b2565b60405180910390fd5b6106a7816138e6565b50565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156106f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071691906153fc565b6107325760405162461bcd60e51b815260040161069590615419565b606654818116146107ab5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610695565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b60008060007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018787600001518860200151886000015160006002811061083157610831615461565b60200201518951600160200201518a6020015160006002811061085657610856615461565b60200201518b6020015160016002811061087257610872615461565b602090810291909101518c518d8301516040516108cf9a99989796959401988952602089019790975260408801959095526060870193909352608086019190915260a085015260c084015260e08301526101008201526101200190565b6040516020818303038152906040528051906020012060001c6108f29190615477565b905061096561090b61090488846139dd565b8690613a74565b610913613b08565b61095b61094c85610946604080518082018252600080825260209182015281518083019092526001825260029082015290565b906139dd565b6109558c613bc8565b90613a74565b886201d4c0613c58565b909890975095505050505050565b60606000846001600160a01b031663683048356040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d99190615395565b90506000856001600160a01b0316639e9923c26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3f9190615395565b90506000866001600160a01b0316635df459466040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa59190615395565b9050600086516001600160401b03811115610ac257610ac26146f7565b604051908082528060200260200182016040528015610af557816020015b6060815260200190600190039081610ae05790505b50905060005b8751811015610dfd576000888281518110610b1857610b18615461565b0160200151604051638902624560e01b815260f89190911c6004820181905263ffffffff8a16602483015291506000906001600160a01b03871690638902624590604401600060405180830381865afa158015610b79573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ba19190810190615499565b905080516001600160401b03811115610bbc57610bbc6146f7565b604051908082528060200260200182016040528015610c0757816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181610bda5790505b50848481518110610c1a57610c1a615461565b602002602001018190525060005b8151811015610de7576040518060600160405280876001600160a01b03166347b314e8858581518110610c5d57610c5d615461565b60200260200101516040518263ffffffff1660e01b8152600401610c8391815260200190565b602060405180830381865afa158015610ca0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc49190615395565b6001600160a01b03168152602001838381518110610ce457610ce4615461565b60200260200101518152602001896001600160a01b031663fa28c627858581518110610d1257610d12615461565b60209081029190910101516040516001600160e01b031960e084901b168152600481019190915260ff8816602482015263ffffffff8f166044820152606401602060405180830381865afa158015610d6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d929190615529565b6001600160601b0316815250858581518110610db057610db0615461565b60200260200101518281518110610dc957610dc9615461565b60200260200101819052508080610ddf90615568565b915050610c28565b5050508080610df590615568565b915050610afb565b50979650505050505050565b7f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc96001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8b9190615395565b6001600160a01b0316336001600160a01b031614610f375760405162461bcd60e51b815260206004820152605c60248201527f424c535369676e6174757265436865636b65722e6f6e6c79436f6f7264696e6160448201527f746f724f776e65723a2063616c6c6572206973206e6f7420746865206f776e6560648201527f72206f6620746865207265676973747279436f6f7264696e61746f7200000000608482015260a401610695565b6097805460ff19168215159081179091556040519081527f40e4ed880a29e0f6ddce307457fb75cddf4feef7d3ecb0301bfdf4976a0e2dfc9060200160405180910390a150565b610fa96040518060800160405280606081526020016060815260200160608152602001606081525090565b6000876001600160a01b031663683048356040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fe9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100d9190615395565b905061103a6040518060800160405280606081526020016060815260200160608152602001606081525090565b6040516361c8a12f60e11b81526001600160a01b038a169063c391425e9061106a908b9089908990600401615583565b600060405180830381865afa158015611087573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110af91908101906155cd565b81526040516340e03a8160e11b81526001600160a01b038316906381c07502906110e1908b908b908b90600401615684565b600060405180830381865afa1580156110fe573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261112691908101906155cd565b6040820152856001600160401b03811115611143576111436146f7565b60405190808252806020026020018201604052801561117657816020015b60608152602001906001900390816111615790505b50606082015260005b60ff81168711156115b5576000856001600160401b038111156111a4576111a46146f7565b6040519080825280602002602001820160405280156111cd578160200160208202803683370190505b5083606001518360ff16815181106111e7576111e7615461565b602002602001018190525060005b868110156114b55760008c6001600160a01b03166304ec63518a8a8581811061122057611220615461565b905060200201358e8860000151868151811061123e5761123e615461565b60200260200101516040518463ffffffff1660e01b815260040161127b9392919092835263ffffffff918216602084015216604082015260600190565b602060405180830381865afa158015611298573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bc91906156ad565b90506001600160c01b0381166113605760405162461bcd60e51b815260206004820152605c60248201527f4f70657261746f7253746174655265747269657665722e676574436865636b5360448201527f69676e617475726573496e64696365733a206f70657261746f72206d7573742060648201527f6265207265676973746572656420617420626c6f636b6e756d62657200000000608482015260a401610695565b8a8a8560ff1681811061137557611375615461565b6001600160c01b03841692013560f81c9190911c6001908116141590506114a257856001600160a01b031663dd9846b98a8a858181106113b7576113b7615461565b905060200201358d8d8860ff168181106113d3576113d3615461565b6040516001600160e01b031960e087901b1681526004810194909452919091013560f81c60248301525063ffffffff8f166044820152606401602060405180830381865afa158015611429573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144d91906156d6565b85606001518560ff168151811061146657611466615461565b6020026020010151848151811061147f5761147f615461565b63ffffffff909216602092830291909101909101528261149e81615568565b9350505b50806114ad81615568565b9150506111f5565b506000816001600160401b038111156114d0576114d06146f7565b6040519080825280602002602001820160405280156114f9578160200160208202803683370190505b50905060005b8281101561157a5784606001518460ff168151811061152057611520615461565b6020026020010151818151811061153957611539615461565b602002602001015182828151811061155357611553615461565b63ffffffff909216602092830291909101909101528061157281615568565b9150506114ff565b508084606001518460ff168151811061159557611595615461565b6020026020010181905250505080806115ad906156f3565b91505061117f565b506000896001600160a01b0316635df459466040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a9190615395565b60405163354952a360e21b81529091506001600160a01b0382169063d5254a8c9061164d908b908b908e90600401615713565b600060405180830381865afa15801561166a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261169291908101906155cd565b60208301525098975050505050505050565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156116ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171091906153fc565b61172c5760405162461bcd60e51b815260040161069590615419565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b60cd546001600160a01b031633146117c55760405162461bcd60e51b815260206004820152601d60248201527f41676772656761746f72206d757374206265207468652063616c6c65720000006044820152606401610695565b60006117d760408501602086016148ca565b90503660006117e9604087018761573d565b9092509050600061180060808801606089016148ca565b905060ca600061181360208901896148ca565b63ffffffff1663ffffffff168152602001908152602001600020548760405160200161183f9190615783565b60405160208183030381529060405280519060200120146118c85760405162461bcd60e51b815260206004820152603d60248201527f737570706c696564207461736b20646f6573206e6f74206d617463682074686560448201527f206f6e65207265636f7264656420696e2074686520636f6e74726163740000006064820152608401610695565b600060cb816118da60208a018a6148ca565b63ffffffff1663ffffffff16815260200190815260200160002054146119575760405162461bcd60e51b815260206004820152602c60248201527f41676772656761746f722068617320616c726561647920726573706f6e64656460448201526b20746f20746865207461736b60a01b6064820152608401610695565b6119817f000000000000000000000000000000000000000000000000000000000000001e85615824565b63ffffffff164363ffffffff1611156119f25760405162461bcd60e51b815260206004820152602d60248201527f41676772656761746f722068617320726573706f6e64656420746f207468652060448201526c7461736b20746f6f206c61746560981b6064820152608401610695565b600086604051602001611a05919061586a565b604051602081830303815290604052805190602001209050600080611a2d8387878a8c612525565b9150915060005b85811015611b2c578460ff1683602001518281518110611a5657611a56615461565b6020026020010151611a689190615878565b6001600160601b0316606484600001518381518110611a8957611a89615461565b60200260200101516001600160601b0316611aa491906158a7565b1015611b1a576040805162461bcd60e51b81526020600482015260248101919091527f5369676e61746f7269657320646f206e6f74206f776e206174206c656173742060448201527f7468726573686f6c642070657263656e74616765206f6620612071756f72756d6064820152608401610695565b80611b2481615568565b915050611a34565b5060408051808201825263ffffffff43168152602080820184905291519091611b59918c918491016158c6565b6040516020818303038152906040528051906020012060cb60008c6000016020810190611b8691906148ca565b63ffffffff1663ffffffff168152602001908152602001600020819055507f349c1ee60e4e8972ee9dba642c1774543d5c4136879b7f4caaf04bf81a487a2a8a82604051611bd59291906158c6565b60405180910390a15050505050505050505050565b60606000846001600160a01b031663c391425e84866040518363ffffffff1660e01b8152600401611c1c9291906158f2565b600060405180830381865afa158015611c39573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c6191908101906155cd565b9050600084516001600160401b03811115611c7e57611c7e6146f7565b604051908082528060200260200182016040528015611ca7578160200160208202803683370190505b50905060005b8551811015611da857866001600160a01b03166304ec6351878381518110611cd757611cd7615461565b602002602001015187868581518110611cf257611cf2615461565b60200260200101516040518463ffffffff1660e01b8152600401611d2f9392919092835263ffffffff918216602084015216604082015260600190565b602060405180830381865afa158015611d4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d7091906156ad565b6001600160c01b0316828281518110611d8b57611d8b615461565b602090810291909101015280611da081615568565b915050611cad565b5095945050505050565b6000611dc160208501856148ca565b63ffffffff8116600090815260cb6020526040902054909150853590611e335760405162461bcd60e51b815260206004820152602160248201527f5461736b206861736e2774206265656e20726573706f6e64656420746f2079656044820152601d60fa1b6064820152608401610695565b8484604051602001611e46929190615946565b60408051601f19818403018152918152815160209283012063ffffffff8516600090815260cb90935291205414611ee55760405162461bcd60e51b815260206004820152603d60248201527f5461736b20726573706f6e736520646f6573206e6f74206d617463682074686560448201527f206f6e65207265636f7264656420696e2074686520636f6e74726163740000006064820152608401610695565b63ffffffff8216600090815260cc602052604090205460ff1615611f7d5760405162461bcd60e51b815260206004820152604360248201527f54686520726573706f6e736520746f2074686973207461736b2068617320616c60448201527f7265616479206265656e206368616c6c656e676564207375636365737366756c606482015262363c9760e91b608482015260a401610695565b6064611f8c60208601866148ca565b611f969190615824565b63ffffffff164363ffffffff1611156120175760405162461bcd60e51b815260206004820152603760248201527f546865206368616c6c656e676520706572696f6420666f72207468697320746160448201527f736b2068617320616c726561647920657870697265642e0000000000000000006064820152608401610695565b600061202382806158a7565b905060208601358114600181141561207157604051339063ffffffff8616907ffd3e26beeb5967fc5a57a0446914eabc45b4aa474c67a51b4b5160cac60ddb0590600090a35050505061237e565b600085516001600160401b0381111561208c5761208c6146f7565b6040519080825280602002602001820160405280156120b5578160200160208202803683370190505b50905060005b8651811015612127576120f88782815181106120d9576120d9615461565b6020026020010151805160009081526020918201519091526040902090565b82828151811061210a5761210a615461565b60209081029190910101528061211f81615568565b9150506120bb565b50600061213a60408b0160208c016148ca565b8260405160200161214c92919061597c565b604051602081830303815290604052805190602001209050876020013581146121f65760405162461bcd60e51b815260206004820152605060248201527f546865207075626b657973206f66206e6f6e2d7369676e696e67206f7065726160448201527f746f727320737570706c69656420627920746865206368616c6c656e6765722060648201526f30b932903737ba1031b7b93932b1ba1760811b608482015260a401610695565b600087516001600160401b03811115612211576122116146f7565b60405190808252806020026020018201604052801561223a578160200160208202803683370190505b50905060005b885181101561232d577f0000000000000000000000001613beb3b2c4f22ee086b2b38c1476a3ce7f78e86001600160a01b031663e8bb9ae685838151811061228a5761228a615461565b60200260200101516040518263ffffffff1660e01b81526004016122b091815260200190565b602060405180830381865afa1580156122cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122f19190615395565b82828151811061230357612303615461565b6001600160a01b03909216602092830291909101909101528061232581615568565b915050612240565b5063ffffffff8716600081815260cc6020526040808220805460ff19166001179055513392917fc20d1bb0f1623680306b83d4ff4bb99a2beb9d86d97832f3ca40fd13a29df1ec91a3505050505050505b50505050565b60ce546001600160a01b031633146123e85760405162461bcd60e51b815260206004820152602160248201527f5461736b2067656e657261746f72206d757374206265207468652063616c6c656044820152603960f91b6064820152608401610695565b61241f604051806080016040528060008152602001600063ffffffff16815260200160608152602001600063ffffffff1681525090565b84815263ffffffff438116602080840191909152908516606083015260408051601f8501839004830281018301909152838152908490849081908401838280828437600092019190915250505050604080830191909152516124859082906020016159c4565b60408051601f19818403018152828252805160209182012060c9805463ffffffff908116600090815260ca90945293909220555416907f1695b8d06ec800b4615e745cfb5bd00c1f2875615d42925c3b5afa543bb24c48906124e89084906159c4565b60405180910390a260c9546125049063ffffffff166001615824565b60c9805463ffffffff191663ffffffff929092169190911790555050505050565b604080518082019091526060808252602082015260008461259c5760405162461bcd60e51b81526020600482015260376024820152600080516020615b4a83398151915260448201527f7265733a20656d7074792071756f72756d20696e7075740000000000000000006064820152608401610695565b604083015151851480156125b4575060a08301515185145b80156125c4575060c08301515185145b80156125d4575060e08301515185145b61263e5760405162461bcd60e51b81526020600482015260416024820152600080516020615b4a83398151915260448201527f7265733a20696e7075742071756f72756d206c656e677468206d69736d6174636064820152600d60fb1b608482015260a401610695565b825151602084015151146126b65760405162461bcd60e51b815260206004820152604460248201819052600080516020615b4a833981519152908201527f7265733a20696e707574206e6f6e7369676e6572206c656e677468206d69736d6064820152630c2e8c6d60e31b608482015260a401610695565b4363ffffffff168463ffffffff16106127255760405162461bcd60e51b815260206004820152603c6024820152600080516020615b4a83398151915260448201527f7265733a20696e76616c6964207265666572656e636520626c6f636b000000006064820152608401610695565b6040805180820182526000808252602080830191909152825180840190935260608084529083015290866001600160401b03811115612766576127666146f7565b60405190808252806020026020018201604052801561278f578160200160208202803683370190505b506020820152866001600160401b038111156127ad576127ad6146f7565b6040519080825280602002602001820160405280156127d6578160200160208202803683370190505b50815260408051808201909152606080825260208201528560200151516001600160401b0381111561280a5761280a6146f7565b604051908082528060200260200182016040528015612833578160200160208202803683370190505b5081526020860151516001600160401b03811115612853576128536146f7565b60405190808252806020026020018201604052801561287c578160200160208202803683370190505b508160200181905250600061294e8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051639aa1653d60e01b815290516001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc9169350639aa1653d925060048083019260209291908290030181865afa158015612925573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129499190615a4f565b613e7c565b905060005b876020015151811015612bca57612979886020015182815181106120d9576120d9615461565b8360200151828151811061298f5761298f615461565b60209081029190910101528015612a4f5760208301516129b0600183615a6c565b815181106129c0576129c0615461565b602002602001015160001c836020015182815181106129e1576129e1615461565b602002602001015160001c11612a4f576040805162461bcd60e51b8152602060048201526024810191909152600080516020615b4a83398151915260448201527f7265733a206e6f6e5369676e65725075626b657973206e6f7420736f727465646064820152608401610695565b7f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc96001600160a01b03166304ec635184602001518381518110612a9457612a94615461565b60200260200101518b8b600001518581518110612ab357612ab3615461565b60200260200101516040518463ffffffff1660e01b8152600401612af09392919092835263ffffffff918216602084015216604082015260600190565b602060405180830381865afa158015612b0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b3191906156ad565b6001600160c01b031683600001518281518110612b5057612b50615461565b602002602001018181525050612bb6610904612b8a8486600001518581518110612b7c57612b7c615461565b602002602001015116613f0f565b8a602001518481518110612ba057612ba0615461565b6020026020010151613f3a90919063ffffffff16565b945080612bc281615568565b915050612953565b5050612bd58361401e565b60975490935060ff16600081612bec576000612c6e565b7f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc96001600160a01b031663c448feb86040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c6e9190615a83565b905060005b8a8110156132ec578215612dce578963ffffffff16827f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc96001600160a01b031663249a0c428f8f86818110612cca57612cca615461565b60405160e085901b6001600160e01b031916815292013560f81c600483015250602401602060405180830381865afa158015612d0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d2e9190615a83565b612d389190615a9c565b11612dce5760405162461bcd60e51b81526020600482015260666024820152600080516020615b4a83398151915260448201527f7265733a205374616b6552656769737472792075706461746573206d7573742060648201527f62652077697468696e207769746864726177616c44656c6179426c6f636b732060848201526577696e646f7760d01b60a482015260c401610695565b7f0000000000000000000000001613beb3b2c4f22ee086b2b38c1476a3ce7f78e86001600160a01b03166368bccaac8d8d84818110612e0f57612e0f615461565b9050013560f81c60f81b60f81c8c8c60a001518581518110612e3357612e33615461565b60209081029190910101516040516001600160e01b031960e086901b16815260ff909316600484015263ffffffff9182166024840152166044820152606401602060405180830381865afa158015612e8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eb39190615ab4565b6001600160401b031916612ed68a6040015183815181106120d9576120d9615461565b67ffffffffffffffff191614612f725760405162461bcd60e51b81526020600482015260616024820152600080516020615b4a83398151915260448201527f7265733a2071756f72756d41706b206861736820696e2073746f72616765206460648201527f6f6573206e6f74206d617463682070726f76696465642071756f72756d2061706084820152606b60f81b60a482015260c401610695565b612fa289604001518281518110612f8b57612f8b615461565b602002602001015187613a7490919063ffffffff16565b95507f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f366001600160a01b031663c8294c568d8d84818110612fe557612fe5615461565b9050013560f81c60f81b60f81c8c8c60c00151858151811061300957613009615461565b60209081029190910101516040516001600160e01b031960e086901b16815260ff909316600484015263ffffffff9182166024840152166044820152606401602060405180830381865afa158015613065573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130899190615529565b8560200151828151811061309f5761309f615461565b6001600160601b039092166020928302919091018201528501518051829081106130cb576130cb615461565b6020026020010151856000015182815181106130e9576130e9615461565b60200260200101906001600160601b031690816001600160601b0316815250506000805b8a60200151518110156132d7576131618660000151828151811061313357613133615461565b60200260200101518f8f8681811061314d5761314d615461565b600192013560f81c9290921c811614919050565b156132c5577f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f366001600160a01b031663f2be94ae8f8f868181106131a7576131a7615461565b9050013560f81c60f81b60f81c8e896020015185815181106131cb576131cb615461565b60200260200101518f60e0015188815181106131e9576131e9615461565b6020026020010151878151811061320257613202615461565b60209081029190910101516040516001600160e01b031960e087901b16815260ff909416600485015263ffffffff92831660248501526044840191909152166064820152608401602060405180830381865afa158015613266573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061328a9190615529565b875180518590811061329e5761329e615461565b602002602001018181516132b29190615adf565b6001600160601b03169052506001909101905b806132cf81615568565b91505061310d565b505080806132e490615568565b915050612c73565b5050506000806133068c868a606001518b608001516107e9565b91509150816133775760405162461bcd60e51b81526020600482015260436024820152600080516020615b4a83398151915260448201527f7265733a2070616972696e6720707265636f6d70696c652063616c6c206661696064820152621b195960ea1b608482015260a401610695565b806133d85760405162461bcd60e51b81526020600482015260396024820152600080516020615b4a83398151915260448201527f7265733a207369676e617475726520697320696e76616c6964000000000000006064820152608401610695565b505060008782602001516040516020016133f392919061597c565b60408051808303601f190181529190528051602090910120929b929a509198505050505050505050565b6134256140b9565b61342f6000614113565b565b604080516001808252818301909252600091606091839160208083019080368337019050509050848160008151811061346c5761346c615461565b60209081029190910101526040516361c8a12f60e11b81526000906001600160a01b0388169063c391425e906134a890889086906004016158f2565b600060405180830381865afa1580156134c5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134ed91908101906155cd565b6000815181106134ff576134ff615461565b60209081029190910101516040516304ec635160e01b81526004810188905263ffffffff87811660248301529091166044820181905291506000906001600160a01b038916906304ec635190606401602060405180830381865afa15801561356b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358f91906156ad565b6001600160c01b0316905060006135a582614165565b9050816135b38a838a610973565b9550955050505050935093915050565b6135cb6140b9565b6001600160a01b0381166136305760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610695565b6106a781614113565b600054610100900460ff16158080156136595750600054600160ff909116105b806136735750303b158015613673575060005460ff166001145b6136d65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610695565b6000805460ff1916600117905580156136f9576000805461ff0019166101001790555b613704856000614231565b61370d84614113565b60cd80546001600160a01b038086166001600160a01b03199283161790925560ce8054928516929091169190911790558015613783576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138019190615395565b6001600160a01b0316336001600160a01b0316146138315760405162461bcd60e51b8152600401610695906153b2565b6066541981196066541916146138af5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610695565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c906020016107de565b6001600160a01b0381166139745760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610695565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b60408051808201909152600080825260208201526139f96145d2565b835181526020808501519082015260408082018490526000908360608460076107d05a03fa9050808015613a2c57613a2e565bfe5b5080613a6c5760405162461bcd60e51b815260206004820152600d60248201526c1958cb5b5d5b0b59985a5b1959609a1b6044820152606401610695565b505092915050565b6040805180820190915260008082526020820152613a906145f0565b835181526020808501518183015283516040808401919091529084015160608301526000908360808460066107d05a03fa9050808015613a2c575080613a6c5760405162461bcd60e51b815260206004820152600d60248201526c1958cb5859190b59985a5b1959609a1b6044820152606401610695565b613b1061460e565b50604080516080810182527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c28183019081527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6060830152815281518083019092527f275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec82527f1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d60208381019190915281019190915290565b604080518082019091526000808252602082015260008080613bf8600080516020615b2a83398151915286615477565b90505b613c048161431b565b9093509150600080516020615b2a833981519152828309831415613c3e576040805180820190915290815260208101919091529392505050565b600080516020615b2a833981519152600182089050613bfb565b604080518082018252868152602080820186905282518084019093528683528201849052600091829190613c8a614633565b60005b6002811015613e4f576000613ca38260066158a7565b9050848260028110613cb757613cb7615461565b60200201515183613cc9836000615a9c565b600c8110613cd957613cd9615461565b6020020152848260028110613cf057613cf0615461565b60200201516020015183826001613d079190615a9c565b600c8110613d1757613d17615461565b6020020152838260028110613d2e57613d2e615461565b6020020151515183613d41836002615a9c565b600c8110613d5157613d51615461565b6020020152838260028110613d6857613d68615461565b6020020151516001602002015183613d81836003615a9c565b600c8110613d9157613d91615461565b6020020152838260028110613da857613da8615461565b602002015160200151600060028110613dc357613dc3615461565b602002015183613dd4836004615a9c565b600c8110613de457613de4615461565b6020020152838260028110613dfb57613dfb615461565b602002015160200151600160028110613e1657613e16615461565b602002015183613e27836005615a9c565b600c8110613e3757613e37615461565b60200201525080613e4781615568565b915050613c8d565b50613e58614652565b60006020826101808560088cfa9151919c9115159b50909950505050505050505050565b600080613e888461439d565b9050808360ff166001901b11613f065760405162461bcd60e51b815260206004820152603f60248201527f4269746d61705574696c732e6f72646572656442797465734172726179546f4260448201527f69746d61703a206269746d61702065786365656473206d61782076616c7565006064820152608401610695565b90505b92915050565b6000805b8215613f0957613f24600184615a6c565b9092169180613f3281615b07565b915050613f13565b60408051808201909152600080825260208201526102008261ffff1610613f965760405162461bcd60e51b815260206004820152601060248201526f7363616c61722d746f6f2d6c6172676560801b6044820152606401610695565b8161ffff1660011415613faa575081613f09565b6040805180820190915260008082526020820181905284906001905b8161ffff168661ffff161061401357600161ffff871660ff83161c81161415613ff657613ff38484613a74565b93505b6140008384613a74565b92506201fffe600192831b169101613fc6565b509195945050505050565b6040805180820190915260008082526020820152815115801561404357506020820151155b15614061575050604080518082019091526000808252602082015290565b604051806040016040528083600001518152602001600080516020615b2a83398151915284602001516140949190615477565b6140ac90600080516020615b2a833981519152615a6c565b905292915050565b919050565b6033546001600160a01b0316331461342f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610695565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b606060008061417384613f0f565b61ffff166001600160401b0381111561418e5761418e6146f7565b6040519080825280601f01601f1916602001820160405280156141b8576020820181803683370190505b5090506000805b8251821080156141d0575061010081105b15614227576001811b935085841615614217578060f81b8383815181106141f9576141f9615461565b60200101906001600160f81b031916908160001a9053508160010191505b61422081615568565b90506141bf565b5090949350505050565b6065546001600160a01b031615801561425257506001600160a01b03821615155b6142d45760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610695565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2614317826138e6565b5050565b60008080600080516020615b2a8339815191526003600080516020615b2a83398151915286600080516020615b2a833981519152888909090890506000614391827f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52600080516020615b2a83398151915261452a565b91959194509092505050565b6000610100825111156144265760405162461bcd60e51b8152602060048201526044602482018190527f4269746d61705574696c732e6f72646572656442797465734172726179546f42908201527f69746d61703a206f7264657265644279746573417272617920697320746f6f206064820152636c6f6e6760e01b608482015260a401610695565b815161443457506000919050565b6000808360008151811061444a5761444a615461565b0160200151600160f89190911c81901b92505b84518110156145215784818151811061447857614478615461565b0160200151600160f89190911c1b915082821161450d5760405162461bcd60e51b815260206004820152604760248201527f4269746d61705574696c732e6f72646572656442797465734172726179546f4260448201527f69746d61703a206f72646572656442797465734172726179206973206e6f74206064820152661bdc99195c995960ca1b608482015260a401610695565b9181179161451a81615568565b905061445d565b50909392505050565b600080614535614652565b61453d614670565b602080825281810181905260408201819052606082018890526080820187905260a082018690528260c08360056107d05a03fa9250828015613a2c5750826145c75760405162461bcd60e51b815260206004820152601a60248201527f424e3235342e6578704d6f643a2063616c6c206661696c7572650000000000006044820152606401610695565b505195945050505050565b60405180606001604052806003906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b604051806040016040528061462161468e565b815260200161462e61468e565b905290565b604051806101800160405280600c906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180604001604052806002906020820280368337509192915050565b6001600160a01b03811681146106a757600080fd5b6000602082840312156146d357600080fd5b8135613f06816146ac565b6000602082840312156146f057600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561472f5761472f6146f7565b60405290565b60405161010081016001600160401b038111828210171561472f5761472f6146f7565b604051601f8201601f191681016001600160401b0381118282101715614780576147806146f7565b604052919050565b60006040828403121561479a57600080fd5b6147a261470d565b9050813581526020820135602082015292915050565b600082601f8301126147c957600080fd5b604051604081018181106001600160401b03821117156147eb576147eb6146f7565b806040525080604084018581111561480257600080fd5b845b81811015614013578035835260209283019201614804565b60006080828403121561482e57600080fd5b61483661470d565b905061484283836147b8565b815261485183604084016147b8565b602082015292915050565b600080600080610120858703121561487357600080fd5b843593506148848660208701614788565b9250614893866060870161481c565b91506148a28660e08701614788565b905092959194509250565b63ffffffff811681146106a757600080fd5b80356140b4816148ad565b6000602082840312156148dc57600080fd5b8135613f06816148ad565b6000806000606084860312156148fc57600080fd5b8335614907816146ac565b92506020848101356001600160401b038082111561492457600080fd5b818701915087601f83011261493857600080fd5b81358181111561494a5761494a6146f7565b61495c601f8201601f19168501614758565b9150808252888482850101111561497257600080fd5b8084840185840137600084828401015250809450505050614995604085016148bf565b90509250925092565b600081518084526020808501808196508360051b810191508286016000805b86811015614a34578385038a52825180518087529087019087870190845b81811015614a1f57835180516001600160a01b031684528a8101518b8501526040908101516001600160601b031690840152928901926060909201916001016149db565b50509a87019a955050918501916001016149bd565b509298975050505050505050565b602081526000614a55602083018461499e565b9392505050565b80151581146106a757600080fd5b600060208284031215614a7c57600080fd5b8135613f0681614a5c565b60008083601f840112614a9957600080fd5b5081356001600160401b03811115614ab057600080fd5b602083019150836020828501011115614ac857600080fd5b9250929050565b60008060008060008060808789031215614ae857600080fd5b8635614af3816146ac565b95506020870135614b03816148ad565b945060408701356001600160401b0380821115614b1f57600080fd5b614b2b8a838b01614a87565b90965094506060890135915080821115614b4457600080fd5b818901915089601f830112614b5857600080fd5b813581811115614b6757600080fd5b8a60208260051b8501011115614b7c57600080fd5b6020830194508093505050509295509295509295565b600081518084526020808501945080840160005b83811015614bc857815163ffffffff1687529582019590820190600101614ba6565b509495945050505050565b600060208083528351608082850152614bef60a0850182614b92565b905081850151601f1980868403016040870152614c0c8383614b92565b92506040870151915080868403016060870152614c298383614b92565b60608801518782038301608089015280518083529194508501925084840190600581901b8501860160005b82811015614c805784878303018452614c6e828751614b92565b95880195938801939150600101614c54565b509998505050505050505050565b60ff811681146106a757600080fd5b600060208284031215614caf57600080fd5b8135613f0681614c8e565b600060808284031215614ccc57600080fd5b50919050565b600060408284031215614ccc57600080fd5b60006001600160401b03821115614cfd57614cfd6146f7565b5060051b60200190565b600082601f830112614d1857600080fd5b81356020614d2d614d2883614ce4565b614758565b82815260059290921b84018101918181019086841115614d4c57600080fd5b8286015b84811015614d70578035614d63816148ad565b8352918301918301614d50565b509695505050505050565b600082601f830112614d8c57600080fd5b81356020614d9c614d2883614ce4565b82815260069290921b84018101918181019086841115614dbb57600080fd5b8286015b84811015614d7057614dd18882614788565b835291830191604001614dbf565b600082601f830112614df057600080fd5b81356020614e00614d2883614ce4565b82815260059290921b84018101918181019086841115614e1f57600080fd5b8286015b84811015614d705780356001600160401b03811115614e425760008081fd5b614e508986838b0101614d07565b845250918301918301614e23565b60006101808284031215614e7157600080fd5b614e79614735565b905081356001600160401b0380821115614e9257600080fd5b614e9e85838601614d07565b83526020840135915080821115614eb457600080fd5b614ec085838601614d7b565b60208401526040840135915080821115614ed957600080fd5b614ee585838601614d7b565b6040840152614ef7856060860161481c565b6060840152614f098560e08601614788565b6080840152610120840135915080821115614f2357600080fd5b614f2f85838601614d07565b60a0840152610140840135915080821115614f4957600080fd5b614f5585838601614d07565b60c0840152610160840135915080821115614f6f57600080fd5b50614f7c84828501614ddf565b60e08301525092915050565b600080600060808486031215614f9d57600080fd5b83356001600160401b0380821115614fb457600080fd5b614fc087838801614cba565b9450614fcf8760208801614cd2565b93506060860135915080821115614fe557600080fd5b50614ff286828701614e5e565b9150509250925092565b60008060006060848603121561501157600080fd5b833561501c816146ac565b92506020848101356001600160401b0381111561503857600080fd5b8501601f8101871361504957600080fd5b8035615057614d2882614ce4565b81815260059190911b8201830190838101908983111561507657600080fd5b928401925b828410156150945783358252928401929084019061507b565b8096505050505050614995604085016148bf565b6020808252825182820181905260009190848201906040850190845b818110156150e0578351835292840192918401916001016150c4565b50909695505050505050565b60008060008060c0858703121561510257600080fd5b84356001600160401b038082111561511957600080fd5b61512588838901614cba565b95506151348860208901614cd2565b94506151438860608901614cd2565b935060a087013591508082111561515957600080fd5b5061516687828801614d7b565b91505092959194509250565b6000806000806060858703121561518857600080fd5b84359350602085013561519a816148ad565b925060408501356001600160401b038111156151b557600080fd5b6151c187828801614a87565b95989497509550505050565b6000806000806000608086880312156151e557600080fd5b8535945060208601356001600160401b038082111561520357600080fd5b61520f89838a01614a87565b909650945060408801359150615224826148ad565b9092506060870135908082111561523a57600080fd5b5061524788828901614e5e565b9150509295509295909350565b600081518084526020808501945080840160005b83811015614bc85781516001600160601b031687529582019590820190600101615268565b60408152600083516040808401526152a86080840182615254565b90506020850151603f198483030160608501526152c58282615254565b925050508260208301529392505050565b6000806000606084860312156152eb57600080fd5b83356152f6816146ac565b925060208401359150604084013561530d816148ad565b809150509250925092565b828152604060208201526000615331604083018461499e565b949350505050565b6000806000806080858703121561534f57600080fd5b843561535a816146ac565b9350602085013561536a816146ac565b9250604085013561537a816146ac565b9150606085013561538a816146ac565b939692955090935050565b6000602082840312156153a757600080fd5b8151613f06816146ac565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b60006020828403121561540e57600080fd5b8151613f0681614a5c565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60008261549457634e487b7160e01b600052601260045260246000fd5b500690565b600060208083850312156154ac57600080fd5b82516001600160401b038111156154c257600080fd5b8301601f810185136154d357600080fd5b80516154e1614d2882614ce4565b81815260059190911b8201830190838101908783111561550057600080fd5b928401925b8284101561551e57835182529284019290840190615505565b979650505050505050565b60006020828403121561553b57600080fd5b81516001600160601b0381168114613f0657600080fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141561557c5761557c615552565b5060010190565b63ffffffff84168152604060208201819052810182905260006001600160fb1b038311156155b057600080fd5b8260051b8085606085013760009201606001918252509392505050565b600060208083850312156155e057600080fd5b82516001600160401b038111156155f657600080fd5b8301601f8101851361560757600080fd5b8051615615614d2882614ce4565b81815260059190911b8201830190838101908783111561563457600080fd5b928401925b8284101561551e57835161564c816148ad565b82529284019290840190615639565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b63ffffffff841681526040602082015260006156a460408301848661565b565b95945050505050565b6000602082840312156156bf57600080fd5b81516001600160c01b0381168114613f0657600080fd5b6000602082840312156156e857600080fd5b8151613f06816148ad565b600060ff821660ff81141561570a5761570a615552565b60010192915050565b60408152600061572760408301858761565b565b905063ffffffff83166020830152949350505050565b6000808335601e1984360301811261575457600080fd5b8301803591506001600160401b0382111561576e57600080fd5b602001915036819003821315614ac857600080fd5b60208152813560208201526000602083013561579e816148ad565b63ffffffff81166040840152506040830135601e198436030181126157c257600080fd5b830180356001600160401b038111156157da57600080fd5b8036038513156157e957600080fd5b6080606085015261580160a08501826020850161565b565b915050615810606085016148bf565b63ffffffff81166080850152509392505050565b600063ffffffff80831681851680830382111561584357615843615552565b01949350505050565b8035615857816148ad565b63ffffffff168252602090810135910152565b60408101613f09828461584c565b60006001600160601b038083168185168183048111821515161561589e5761589e615552565b02949350505050565b60008160001904831182151516156158c1576158c1615552565b500290565b608081016158d4828561584c565b63ffffffff8351166040830152602083015160608301529392505050565b60006040820163ffffffff851683526020604081850152818551808452606086019150828701935060005b818110156159395784518352938301939183019160010161591d565b5090979650505050505050565b60808101615954828561584c565b823561595f816148ad565b63ffffffff16604083015260209290920135606090910152919050565b63ffffffff60e01b8360e01b1681526000600482018351602080860160005b838110156159b75781518552938201939082019060010161599b565b5092979650505050505050565b6000602080835283518184015263ffffffff8185015116604084015260408401516080606085015280518060a086015260005b81811015615a135782810184015186820160c0015283016159f7565b81811115615a2557600060c083880101525b50606086015163ffffffff811660808701529250601f01601f19169390930160c001949350505050565b600060208284031215615a6157600080fd5b8151613f0681614c8e565b600082821015615a7e57615a7e615552565b500390565b600060208284031215615a9557600080fd5b5051919050565b60008219821115615aaf57615aaf615552565b500190565b600060208284031215615ac657600080fd5b815167ffffffffffffffff1981168114613f0657600080fd5b60006001600160601b0383811690831681811015615aff57615aff615552565b039392505050565b600061ffff80831681811415615b1f57615b1f615552565b600101939250505056fe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47424c535369676e6174757265436865636b65722e636865636b5369676e617475a2646970667358221220f43d3574c3acebcece2bc7051e60a5c5dc7c8feae0125c754c62da48277a982664736f6c634300080c0033","storage":{"0x97":"0x1"}},"0x4e59b44847b379578588920ca78fbf26c0b4956c":{"nonce":0,"balance":"0x0","code":"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3","storage":{}},"0x5fbdb2315678afecb367f032d93f642f64180aa3":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461011157806399a88ec414610124578063f2fde38b14610144578063f3b7dead1461016457600080fd5b8063204e1c7a14610080578063715018a6146100bc5780637eff275e146100d35780638da5cb5b146100f3575b600080fd5b34801561008c57600080fd5b506100a061009b366004610499565b610184565b6040516001600160a01b03909116815260200160405180910390f35b3480156100c857600080fd5b506100d1610215565b005b3480156100df57600080fd5b506100d16100ee3660046104bd565b610229565b3480156100ff57600080fd5b506000546001600160a01b03166100a0565b6100d161011f36600461050c565b610291565b34801561013057600080fd5b506100d161013f3660046104bd565b610300565b34801561015057600080fd5b506100d161015f366004610499565b610336565b34801561017057600080fd5b506100a061017f366004610499565b6103b4565b6000806000836001600160a01b03166040516101aa90635c60da1b60e01b815260040190565b600060405180830381855afa9150503d80600081146101e5576040519150601f19603f3d011682016040523d82523d6000602084013e6101ea565b606091505b5091509150816101f957600080fd5b8080602001905181019061020d91906105e2565b949350505050565b61021d6103da565b6102276000610434565b565b6102316103da565b6040516308f2839760e41b81526001600160a01b038281166004830152831690638f283970906024015b600060405180830381600087803b15801561027557600080fd5b505af1158015610289573d6000803e3d6000fd5b505050505050565b6102996103da565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906102c990869086906004016105ff565b6000604051808303818588803b1580156102e257600080fd5b505af11580156102f6573d6000803e3d6000fd5b5050505050505050565b6103086103da565b604051631b2ce7f360e11b81526001600160a01b038281166004830152831690633659cfe69060240161025b565b61033e6103da565b6001600160a01b0381166103a85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6103b181610434565b50565b6000806000836001600160a01b03166040516101aa906303e1469160e61b815260040190565b6000546001600160a01b031633146102275760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161039f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146103b157600080fd5b6000602082840312156104ab57600080fd5b81356104b681610484565b9392505050565b600080604083850312156104d057600080fd5b82356104db81610484565b915060208301356104eb81610484565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561052157600080fd5b833561052c81610484565b9250602084013561053c81610484565b9150604084013567ffffffffffffffff8082111561055957600080fd5b818601915086601f83011261056d57600080fd5b81358181111561057f5761057f6104f6565b604051601f8201601f19908116603f011681019083821181831017156105a7576105a76104f6565b816040528281528960208487010111156105c057600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156105f457600080fd5b81516104b681610484565b60018060a01b038316815260006020604081840152835180604085015260005b8181101561063b5785810183015185820160600152820161061f565b8181111561064d576000606083870101525b50601f01601f19169290920160600194935050505056fea26469706673582212200fdbd2e25973eab45d03ab46d4fda931522c5b45bccd7b63ecf3c38942f8913564736f6c634300080c0033","storage":{"0x0":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"}},"0x5fc8d32690cc91d4c39d9d3abcbd16989f875707":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033","storage":{"0x0":"0x1","0x33":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x65":"0xe7f1725e7734ce288f8367e1bb143e90bb3f0512","0x66":"0x0","0x97":"0x5bc5b424ff8db9bd8202cae3beb193c946b905d8ebddb990e36a723af40eb1c4","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0xdcd1bf9a1b36ce34237eeafef220932846bcd82","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0x610178da211fef7d417bc0e6fed39f05609ad788":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106100575760003560e01c80633659cfe61461005c5780635c60da1b14610071578063715018a61461009a5780638da5cb5b146100a2578063f2fde38b146100b3575b600080fd5b61006f61006a3660046102ee565b6100c6565b005b6001546001600160a01b03165b6040516001600160a01b03909116815260200160405180910390f35b61006f61010e565b6000546001600160a01b031661007e565b61006f6100c13660046102ee565b610122565b6100ce6101af565b6100d781610209565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6101166101af565b610120600061029e565b565b61012a6101af565b6001600160a01b0381166101945760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61019d8161029e565b50565b6001600160a01b03163b151590565b6000546001600160a01b031633146101205760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161018b565b6001600160a01b0381163b61027c5760405162461bcd60e51b815260206004820152603360248201527f5570677261646561626c65426561636f6e3a20696d706c656d656e746174696f6044820152721b881a5cc81b9bdd08184818dbdb9d1c9858dd606a1b606482015260840161018b565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561030057600080fd5b81356001600160a01b038116811461031757600080fd5b939250505056fea2646970667358221220a22223d3e2a2d861ad54e68b7bc44b4d82a5a12a0bcca5c3404502bb1b430c5c64736f6c634300080c0033","storage":{"0x0":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x1":"0x8a791620dd6260079bf849dc5567adc3f2fdc318"}},"0x67d269191c92caf3cd7723f116c85e6e9bf55933":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461011157806399a88ec414610124578063f2fde38b14610144578063f3b7dead1461016457600080fd5b8063204e1c7a14610080578063715018a6146100bc5780637eff275e146100d35780638da5cb5b146100f3575b600080fd5b34801561008c57600080fd5b506100a061009b366004610499565b610184565b6040516001600160a01b03909116815260200160405180910390f35b3480156100c857600080fd5b506100d1610215565b005b3480156100df57600080fd5b506100d16100ee3660046104bd565b610229565b3480156100ff57600080fd5b506000546001600160a01b03166100a0565b6100d161011f36600461050c565b610291565b34801561013057600080fd5b506100d161013f3660046104bd565b610300565b34801561015057600080fd5b506100d161015f366004610499565b610336565b34801561017057600080fd5b506100a061017f366004610499565b6103b4565b6000806000836001600160a01b03166040516101aa90635c60da1b60e01b815260040190565b600060405180830381855afa9150503d80600081146101e5576040519150601f19603f3d011682016040523d82523d6000602084013e6101ea565b606091505b5091509150816101f957600080fd5b8080602001905181019061020d91906105e2565b949350505050565b61021d6103da565b6102276000610434565b565b6102316103da565b6040516308f2839760e41b81526001600160a01b038281166004830152831690638f283970906024015b600060405180830381600087803b15801561027557600080fd5b505af1158015610289573d6000803e3d6000fd5b505050505050565b6102996103da565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906102c990869086906004016105ff565b6000604051808303818588803b1580156102e257600080fd5b505af11580156102f6573d6000803e3d6000fd5b5050505050505050565b6103086103da565b604051631b2ce7f360e11b81526001600160a01b038281166004830152831690633659cfe69060240161025b565b61033e6103da565b6001600160a01b0381166103a85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6103b181610434565b50565b6000806000836001600160a01b03166040516101aa906303e1469160e61b815260040190565b6000546001600160a01b031633146102275760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161039f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146103b157600080fd5b6000602082840312156104ab57600080fd5b81356104b681610484565b9392505050565b600080604083850312156104d057600080fd5b82356104db81610484565b915060208301356104eb81610484565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561052157600080fd5b833561052c81610484565b9250602084013561053c81610484565b9150604084013567ffffffffffffffff8082111561055957600080fd5b818601915086601f83011261056d57600080fd5b81358181111561057f5761057f6104f6565b604051601f8201601f19908116603f011681019083821181831017156105a7576105a76104f6565b816040528281528960208487010111156105c057600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156105f457600080fd5b81516104b681610484565b60018060a01b038316815260006020604081840152835180604085015260005b8181101561063b5785810183015185820160600152820161061f565b8181111561064d576000606083870101525b50601f01601f19169290920160600194935050505056fea2646970667358221220256db6e93a752df3d0dccc3089617e209be80b9bc8901c1caeb7e0311892a77464736f6c634300080c0033","storage":{"0x0":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"}},"0x70997970c51812dc3a010c7d01b50e0d17dc79c8":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x7a2088a1bfc9d81c55368ae168c2c02570cb814f":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b506004361061007d5760003560e01c806340c10f191161005b57806340c10f19146100d257806370a08231146100e7578063a9059cbb14610110578063dd62ed3e1461012357600080fd5b8063095ea7b31461008257806318160ddd146100ad57806323b872dd146100bf575b600080fd5b610098610090366004610410565b600192915050565b60405190151581526020015b60405180910390f35b6002545b6040519081526020016100a4565b6100986100cd36600461043a565b61015c565b6100e56100e0366004610410565b610173565b005b6100b16100f5366004610476565b6001600160a01b031660009081526020819052604090205490565b61009861011e366004610410565b610181565b6100b1610131366004610498565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600061016984848461018b565b5060019392505050565b61017d8282610335565b5050565b6000336101698185855b6001600160a01b0383166101f45760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084015b60405180910390fd5b6001600160a01b0382166102565760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016101eb565b6001600160a01b0383166000908152602081905260409020548111156102cd5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016101eb565b6001600160a01b038381166000818152602081815260408083208054879003905593861680835291849020805486019055925184815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6001600160a01b03821661038b5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016101eb565b806002600082825461039d91906104cb565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b80356001600160a01b038116811461040b57600080fd5b919050565b6000806040838503121561042357600080fd5b61042c836103f4565b946020939093013593505050565b60008060006060848603121561044f57600080fd5b610458846103f4565b9250610466602085016103f4565b9150604084013590509250925092565b60006020828403121561048857600080fd5b610491826103f4565b9392505050565b600080604083850312156104ab57600080fd5b6104b4836103f4565b91506104c2602084016103f4565b90509250929050565b600082198211156104ec57634e487b7160e01b600052601160045260246000fd5b50019056fea26469706673582212200c8f4a0047ca0322c22cf7e6a789abbe36ca3141cd508f864ec741dccdc347f964736f6c634300080c0033","storage":{}},"0x84ea74d481ee0a5332c457a4d796187f6ba67feb":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122007c3990e071012e67e928be8d71cb1c6b5ed96fee92e98c9e70cc231dee7232064736f6c634300080c0033","storage":{"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x36c02da8a0983159322a80ffe9f24b1acff8b570","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x67d269191c92caf3cd7723f116c85e6e9bf55933"}},"0x851356ae760d987e095750cceb3bc6014560891c":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122007c3990e071012e67e928be8d71cb1c6b5ed96fee92e98c9e70cc231dee7232064736f6c634300080c0033","storage":{"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0xe801d84fa97b50751dbf25036d067dcf18858bf","0x3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff":"0x1","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x67d269191c92caf3cd7723f116c85e6e9bf55933","0xcfb339bd1c51c488f6134f4ac63d1594afad827b3401c3fc51ed1da74a8ca14e":"0x5"}},"0x860b6912c2d0337ef05bbc89b0c2cb6cbaeab4a5":{"nonce":0,"balance":"0x8ac7230489e80000","code":"0x","storage":{}},"0x8a791620dd6260079bf849dc5567adc3f2fdc318":{"nonce":1,"balance":"0x0","code":"0x6080604052600436106101855760003560e01c806374cdd798116100d1578063c49074421161008a578063e251ef5211610064578063e251ef5214610563578063e2c8344514610583578063f2882461146105a3578063fe80b087146105d757600080fd5b8063c490744214610503578063c4d66de814610523578063dda3346c1461054357600080fd5b806374cdd7981461044057806387e0d289146104745780639b4e46341461049b578063a50600f4146104ae578063b522538a146104ce578063baa7145a146104ee57600080fd5b806334bea20a1161013e57806358eaee791161011857806358eaee791461038f5780635d3f65b6146103bc5780636fcd0e53146103dc5780637439841f1461040957600080fd5b806334bea20a146103005780633f65cf191461033b5780634665bcda1461035b57600080fd5b80630b18ff66146101db5780630cd4649e146102185780631a5057be1461022f5780631d905d5c146102635780633106ab53146102af5780633474aa16146102e057600080fd5b366101d657346037600082825461019c9190614b56565b90915550506040513481527f6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf499060200160405180910390a1005b600080fd5b3480156101e757600080fd5b506033546101fb906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561022457600080fd5b5061022d6105fb565b005b34801561023b57600080fd5b506101fb7f0000000000000000000000002279b7a0a67db372996a5fab50d91eaa73d2ebe681565b34801561026f57600080fd5b506102977f000000000000000000000000000000000000000000000000000000077359400081565b6040516001600160401b03909116815260200161020f565b3480156102bb57600080fd5b506034546102d090600160401b900460ff1681565b604051901515815260200161020f565b3480156102ec57600080fd5b50603454610297906001600160401b031681565b34801561030c57600080fd5b506102d061031b366004614b93565b603560209081526000928352604080842090915290825290205460ff1681565b34801561034757600080fd5b5061022d610356366004614c26565b610764565b34801561036757600080fd5b506101fb7f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85381565b34801561039b57600080fd5b506103af6103aa366004614d37565b610c06565b60405161020f9190614db0565b3480156103c857600080fd5b50603854610297906001600160401b031681565b3480156103e857600080fd5b506103fc6103f7366004614dbe565b610c6b565b60405161020f9190614dd7565b34801561041557600080fd5b506103af610424366004614dbe565b600090815260366020526040902054600160c01b900460ff1690565b34801561044c57600080fd5b506101fb7f00000000000000000000000000000000219ab540356cbb839cbe05303d7705fa81565b34801561048057600080fd5b5060335461029790600160a01b90046001600160401b031681565b61022d6104a9366004614e1f565b610d18565b3480156104ba57600080fd5b5061022d6104c9366004614e92565b610ec5565b3480156104da57600080fd5b506103fc6104e9366004614d37565b611294565b3480156104fa57600080fd5b5061022d611387565b34801561050f57600080fd5b5061022d61051e366004614f3c565b6113f2565b34801561052f57600080fd5b5061022d61053e366004614f68565b61162f565b34801561054f57600080fd5b5061022d61055e366004615082565b611807565b34801561056f57600080fd5b5061022d61057e366004615153565b6119da565b34801561058f57600080fd5b5061022d61059e366004614f3c565b611da5565b3480156105af57600080fd5b506102977f000000000000000000000000000000000000000000000000000000006059f46081565b3480156105e357600080fd5b506105ed60375481565b60405190815260200161020f565b604051635ac86ab760e01b8152600260048201819052907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031690635ac86ab790602401602060405180830381865afa158015610663573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610687919061524e565b156106ad5760405162461bcd60e51b81526004016106a490615270565b60405180910390fd5b6033546001600160a01b031633146106d75760405162461bcd60e51b81526004016106a4906152cd565b603454600160401b900460ff16156107015760405162461bcd60e51b81526004016106a490615315565b6034805460ff60401b1916600160401b179055603354610729906001600160a01b0316611f88565b6033546040516001600160a01b03909116907fca8dfc8c5e0a67a74501c072a3325f685259bebbae7cfd230ab85198a78b70cd90600090a250565b6033546001600160a01b0316331461078e5760405162461bcd60e51b81526004016106a4906152cd565b604051635ac86ab760e01b8152600260048201819052907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031690635ac86ab790602401602060405180830381865afa1580156107f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081a919061524e565b156108375760405162461bcd60e51b81526004016106a490615270565b60335489906001600160401b03600160a01b9091048116908216101561086f5760405162461bcd60e51b81526004016106a490615364565b603454600160401b900460ff166108e75760405162461bcd60e51b815260206004820152603660248201527f456967656e506f642e686173456e61626c656452657374616b696e673a2072656044820152751cdd185ada5b99c81a5cc81b9bdd08195b98589b195960521b60648201526084016106a4565b86851480156108f557508483145b6109855760405162461bcd60e51b815260206004820152605560248201527f456967656e506f642e7665726966795769746864726177616c43726564656e7460448201527f69616c733a2076616c696461746f72496e646963657320616e642070726f6f666064820152740e640daeae6e840c4ca40e6c2daca40d8cadccee8d605b1b608482015260a4016106a4565b4261099b613f486001600160401b038d16614b56565b1015610a245760405162461bcd60e51b815260206004820152604c60248201527f456967656e506f642e7665726966795769746864726177616c43726564656e7460448201527f69616c733a207370656369666965642074696d657374616d7020697320746f6f60648201526b0819985c881a5b881c185cdd60a21b608482015260a4016106a4565b60405163d1c64cc960e01b81526001600160401b038b166004820152610acd907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b03169063d1c64cc990602401602060405180830381865afa158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab991906153f7565b8a35610ac860208d018d615410565b611fbc565b6000805b88811015610b7157610b538c8c358c8c85818110610af157610af1615456565b9050602002016020810190610b06919061546c565b8b8b86818110610b1857610b18615456565b9050602002810190610b2a9190615410565b8b8b88818110610b3c57610b3c615456565b9050602002810190610b4e9190615493565b61214a565b610b5d9083614b56565b915080610b69816154dc565b915050610ad1565b5060335460405163030b147160e61b81526001600160a01b039182166004820152602481018390527f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8539091169063c2c51c4090604401600060405180830381600087803b158015610be157600080fd5b505af1158015610bf5573d6000803e3d6000fd5b505050505050505050505050505050565b600080610c4884848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061260492505050565b600090815260366020526040902054600160c01b900460ff169150505b92915050565b610c936040805160808101825260008082526020820181905291810182905290606082015290565b600082815260366020908152604091829020825160808101845281546001600160401b038082168352600160401b8204811694830194909452600160801b810490931693810193909352906060830190600160c01b900460ff166002811115610cfe57610cfe614d78565b6002811115610d0f57610d0f614d78565b90525092915050565b336001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8531614610d605760405162461bcd60e51b81526004016106a4906154f7565b346801bc16d674ec80000014610dec5760405162461bcd60e51b8152602060048201526044602482018190527f456967656e506f642e7374616b653a206d75737420696e697469616c6c792073908201527f74616b6520666f7220616e792076616c696461746f72207769746820333220656064820152633a3432b960e11b608482015260a4016106a4565b7f00000000000000000000000000000000219ab540356cbb839cbe05303d7705fa6001600160a01b031663228951186801bc16d674ec8000008787610e2f6126fe565b8888886040518863ffffffff1660e01b8152600401610e53969594939291906155c9565b6000604051808303818588803b158015610e6c57600080fd5b505af1158015610e80573d6000803e3d6000fd5b50505050507f606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e238585604051610eb6929190615618565b60405180910390a15050505050565b604051635ac86ab760e01b8152600360048201819052907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031690635ac86ab790602401602060405180830381865afa158015610f2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f51919061524e565b15610f6e5760405162461bcd60e51b81526004016106a490615270565b8684148015610f7c57508382145b6110055760405162461bcd60e51b815260206004820152604e60248201527f456967656e506f642e76657269667942616c616e6365557064617465733a207660448201527f616c696461746f72496e646963657320616e642070726f6f6673206d7573742060648201526d0c4ca40e6c2daca40d8cadccee8d60931b608482015260a4016106a4565b4261101b613f486001600160401b038c16614b56565b101561109d5760405162461bcd60e51b815260206004820152604560248201527f456967656e506f642e76657269667942616c616e6365557064617465733a207360448201527f70656369666965642074696d657374616d7020697320746f6f2066617220696e606482015264081c185cdd60da1b608482015260a4016106a4565b60405163d1c64cc960e01b81526001600160401b038a166004820152611141907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b03169063d1c64cc990602401602060405180830381865afa15801561110e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113291906153f7565b8735610ac860208a018a615410565b6000805b888110156111e5576111c78b8b8b8481811061116357611163615456565b9050602002016020810190611178919061546c565b8a358a8a8681811061118c5761118c615456565b905060200281019061119e9190615410565b8a8a888181106111b0576111b0615456565b90506020028101906111c29190615493565b612743565b6111d1908361562c565b9150806111dd816154dc565b915050611145565b506033546001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85381169163c2c51c40911661122a633b9aca008561566d565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561127057600080fd5b505af1158015611284573d6000803e3d6000fd5b5050505050505050505050505050565b6112bc6040805160808101825260008082526020820181905291810182905290606082015290565b603660006112ff85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061260492505050565b81526020808201929092526040908101600020815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b81049094169281019290925290916060830190600160c01b900460ff16600281111561136c5761136c614d78565b600281111561137d5761137d614d78565b9052509392505050565b6033546001600160a01b031633146113b15760405162461bcd60e51b81526004016106a4906152cd565b603454600160401b900460ff16156113db5760405162461bcd60e51b81526004016106a490615315565b6033546113f0906001600160a01b0316611f88565b565b336001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c853161461143a5760405162461bcd60e51b81526004016106a4906154f7565b611448633b9aca0082615708565b156114d25760405162461bcd60e51b815260206004820152604e60248201527f456967656e506f642e776974686472617752657374616b6564426561636f6e4360448201527f6861696e4554483a20616d6f756e74576569206d75737420626520612077686f60648201526d1b194811ddd95a48185b5bdd5b9d60921b608482015260a4016106a4565b60006114e2633b9aca008361571c565b6034549091506001600160401b03908116908216111561159b5760405162461bcd60e51b815260206004820152606260248201527f456967656e506f642e776974686472617752657374616b6564426561636f6e4360448201527f6861696e4554483a20616d6f756e74477765692065786365656473207769746860648201527f6472617761626c6552657374616b6564457865637574696f6e4c617965724777608482015261656960f01b60a482015260c4016106a4565b603480548291906000906115b99084906001600160401b0316615730565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550826001600160a01b03167f8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e8360405161161891815260200190565b60405180910390a261162a8383612c21565b505050565b600054610100900460ff161580801561164f5750600054600160ff909116105b806116695750303b158015611669575060005460ff166001145b6116cc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106a4565b6000805460ff1916600117905580156116ef576000805461ff0019166101001790555b6001600160a01b0382166117625760405162461bcd60e51b815260206004820152603460248201527f456967656e506f642e696e697469616c697a653a20706f644f776e65722063616044820152736e6e6f74206265207a65726f206164647265737360601b60648201526084016106a4565b603380546001600160a01b0384166001600160a01b031990911681179091556034805460ff60401b1916600160401b1790556040517fca8dfc8c5e0a67a74501c072a3325f685259bebbae7cfd230ab85198a78b70cd90600090a28015611803576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6033546001600160a01b031633146118315760405162461bcd60e51b81526004016106a4906152cd565b604051635ac86ab760e01b8152600560048201819052907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031690635ac86ab790602401602060405180830381865afa158015611899573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118bd919061524e565b156118da5760405162461bcd60e51b81526004016106a490615270565b82518451146119655760405162461bcd60e51b815260206004820152604b60248201527f456967656e506f642e7265636f766572546f6b656e733a20746f6b656e4c697360448201527f7420616e6420616d6f756e7473546f5769746864726177206d7573742062652060648201526a0e6c2daca40d8cadccee8d60ab1b608482015260a4016106a4565b60005b84518110156119d3576119c18385838151811061198757611987615456565b60200260200101518784815181106119a1576119a1615456565b60200260200101516001600160a01b0316612c2b9092919063ffffffff16565b806119cb816154dc565b915050611968565b5050505050565b604051635ac86ab760e01b81526004808201819052907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031690635ac86ab790602401602060405180830381865afa158015611a41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a65919061524e565b15611a825760405162461bcd60e51b81526004016106a490615270565b8386148015611a9057508588145b8015611a9b57508782145b611b0f576040805162461bcd60e51b81526020600482015260248101919091527f456967656e506f642e766572696679416e6450726f636573735769746864726160448201527f77616c733a20696e70757473206d7573742062652073616d65206c656e67746860648201526084016106a4565b60405163d1c64cc960e01b81526001600160401b038c166004820152611bb3907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b03169063d1c64cc990602401602060405180830381865afa158015611b80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba491906153f7565b8b35610ac860208e018e615410565b604080518082019091526000808252602082015260005b83811015611cb3576000611c6e8d358d8d85818110611beb57611beb615456565b9050602002810190611bfd9190615758565b8c8c86818110611c0f57611c0f615456565b9050602002810190611c219190615410565b8c8c88818110611c3357611c33615456565b9050602002810190611c459190615493565b8c8c8a818110611c5757611c57615456565b9050602002810190611c699190615493565b612c7d565b80518451919250908490611c83908390614b56565b9052506020808201519084018051611c9c90839061562c565b905250819050611cab816154dc565b915050611bca565b50805115611ce2576033548151611ce2916001600160a01b031690611cdd90633b9aca0090615779565b613169565b602081015115611d975760335460208201516001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85381169263c2c51c4092911690611d3890633b9aca009061566d565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611d7e57600080fd5b505af1158015611d92573d6000803e3d6000fd5b505050505b505050505050505050505050565b6033546001600160a01b03163314611dcf5760405162461bcd60e51b81526004016106a4906152cd565b604051635ac86ab760e01b8152600560048201819052907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031690635ac86ab790602401602060405180830381865afa158015611e37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5b919061524e565b15611e785760405162461bcd60e51b81526004016106a490615270565b603754821115611f295760405162461bcd60e51b815260206004820152606a60248201527f456967656e506f642e77697468647261776e6f6e426561636f6e436861696e4560448201527f544842616c616e63655765693a20616d6f756e74546f5769746864726177206960648201527f732067726561746572207468616e206e6f6e426561636f6e436861696e45544860848201526942616c616e636557656960b01b60a482015260c4016106a4565b8160376000828254611f3b9190615798565b90915550506040518281526001600160a01b038416907f30420aacd028abb3c1fd03aba253ae725d6ddd52d16c9ac4cb5742cd43f530969060200160405180910390a261162a8383613169565b6033805467ffffffffffffffff60a01b19164263ffffffff16600160a01b021790556000603755611fb98147613169565b50565b611fc860036020615779565b81146120585760405162461bcd60e51b815260206004820152605360248201527f426561636f6e436861696e50726f6f66732e7665726966795374617465526f6f60448201527f74416761696e73744c6174657374426c6f636b526f6f743a2050726f6f6620686064820152720c2e640d2dcc6dee4e4cac6e840d8cadccee8d606b1b608482015260a4016106a4565b61209d82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250879150600390506131f7565b6121445760405162461bcd60e51b815260206004820152606660248201527f426561636f6e436861696e50726f6f66732e7665726966795374617465526f6f60448201527f74416761696e73744c6174657374426c6f636b526f6f743a20496e76616c696460648201527f206c617465737420626c6f636b2068656164657220726f6f74206d65726b6c6560848201526510383937b7b360d11b60a482015260c4016106a4565b50505050565b60008061218984848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061320f92505050565b6000818152603660209081526040808320815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b8104909416928101929092529394509192906060830190600160c01b900460ff1660028111156121f8576121f8614d78565b600281111561220957612209614d78565b905250905060008160600151600281111561222657612226614d78565b146122cf5760405162461bcd60e51b815260206004820152606760248201527f456967656e506f642e766572696679436f72726563745769746864726177616c60448201527f43726564656e7469616c733a2056616c696461746f72206d757374206265206960648201527f6e61637469766520746f2070726f7665207769746864726177616c2063726564608482015266656e7469616c7360c81b60a482015260c4016106a4565b6122d76126fe565b6122e0906157af565b61231c86868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061323392505050565b146123a35760405162461bcd60e51b815260206004820152604b60248201527f456967656e506f642e766572696679436f72726563745769746864726177616c60448201527f43726564656e7469616c733a2050726f6f66206973206e6f7420666f7220746860648201526a1a5cc8115a59d95b941bd960aa1b608482015260a4016106a4565b60006123e186868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061324892505050565b90506123f18a87878b8b8e61326d565b60398054906000612401836154dc565b90915550506001606083015264ffffffffff891682526001600160401b038b811660408401527f000000000000000000000000000000000000000000000000000000077359400081169082161115612487576001600160401b037f0000000000000000000000000000000000000000000000000000000773594000166020830152612497565b6001600160401b03811660208301525b6000838152603660209081526040918290208451815492860151938601516001600160401b03908116600160801b0267ffffffffffffffff60801b19958216600160401b026001600160801b0319909516919092161792909217928316821781556060850151859391929091839160ff60c01b191668ffffffffffffffffff60801b1990911617600160c01b83600281111561253557612535614d78565b02179055505060405164ffffffffff8b1681527f2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449915060200160405180910390a17f0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df898c84602001516040516125d09392919064ffffffffff9390931683526001600160401b03918216602084015216604082015260600190565b60405180910390a1633b9aca0082602001516001600160401b03166125f59190615779565b9b9a5050505050505050505050565b6000815160301461268d5760405162461bcd60e51b815260206004820152604760248201527f456967656e506f642e5f63616c63756c61746556616c696461746f725075626b60448201527f657948617368206d75737420626520612034382d6279746520424c53207075626064820152666c6963206b657960c81b608482015260a4016106a4565b6040516002906126a49084906000906020016157d3565b60408051601f19818403018152908290526126be91615802565b602060405180830381855afa1580156126db573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610c6591906153f7565b60408051600160f81b60208201526000602182015230606090811b6bffffffffffffffffffffffff1916602c8301529101604051602081830303815290604052905090565b60008061278284848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061324892505050565b905060006127c285858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061320f92505050565b6000818152603660209081526040808320815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b8104909416928101929092529394509192906060830190600160c01b900460ff16600281111561283157612831614d78565b600281111561284257612842614d78565b8152505090508a6001600160401b031681604001516001600160401b0316106128f95760405162461bcd60e51b815260206004820152605c60248201527f456967656e506f642e76657269667942616c616e63655570646174653a20566160448201527f6c696461746f72732062616c616e63652068617320616c72656164792062656560648201527f6e207570646174656420666f7220746869732074696d657374616d7000000000608482015260a4016106a4565b60018160600151600281111561291157612911614d78565b146129795760405162461bcd60e51b815260206004820152603260248201527f456967656e506f642e76657269667942616c616e63655570646174653a2056616044820152716c696461746f72206e6f742061637469766560701b60648201526084016106a4565b6129828b6134c4565b6001600160401b03166129c78787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506135ae92505050565b6001600160401b031611612a6a576000836001600160401b031611612a6a5760405162461bcd60e51b815260206004820152604d60248201527f456967656e506f642e76657269667942616c616e63655570646174653a20766160448201527f6c696461746f7220697320776974686472617761626c6520627574206861732060648201526c3737ba103bb4ba34323930bbb760991b608482015260a4016106a4565b612a788987878b8b8f61326d565b602081015160006001600160401b037f000000000000000000000000000000000000000000000000000000077359400081169086161115612ada57507f0000000000000000000000000000000000000000000000000000000773594000612add565b50835b6001600160401b0380821660208086019182528f831660408088019182526000898152603690935290912086518154935192518516600160801b0267ffffffffffffffff60801b19938616600160401b026001600160801b031990951691909516179290921790811683178255606086015186939091839160ff60c01b191668ffffffffffffffffff60801b1990911617600160c01b836002811115612b8557612b85614d78565b0217905550905050816001600160401b0316816001600160401b031614612c11577f0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df8c8e83604051612bfc9392919064ffffffffff9390931683526001600160401b03918216602084015216604082015260600190565b60405180910390a1612c0e81836135c6565b95505b5050505050979650505050505050565b61180382826135e5565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261162a9084906136fe565b6040805180820190915260008082526020820152612ca2612c9d89615883565b6137d0565b6033546001600160401b03600160a01b90910481169082161015612cd85760405162461bcd60e51b81526004016106a490615364565b6000612ce6612c9d8b615883565b90506000612d2688888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061320f92505050565b905060008082815260366020526040902054600160c01b900460ff166002811115612d5357612d53614d78565b1415612e0a5760405162461bcd60e51b815260206004820152607460248201527f456967656e506f642e5f766572696679416e6450726f6365737357697468647260448201527f6177616c3a2056616c696461746f72206e657665722070726f76656e20746f2060648201527f68617665207769746864726177616c2063726564656e7469616c7320706f696e6084820152731d1959081d1bc81d1a1a5cc818dbdb9d1c9858dd60621b60a482015260c4016106a4565b60008181526035602090815260408083206001600160401b038616845290915290205460ff1615612ec95760405162461bcd60e51b815260206004820152605b60248201527f456967656e506f642e5f766572696679416e6450726f6365737357697468647260448201527f6177616c3a207769746864726177616c2068617320616c72656164792062656560648201527f6e2070726f76656e20666f7220746869732074696d657374616d700000000000608482015260a4016106a4565b6001603560008381526020019081526020016000206000846001600160401b03166001600160401b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550612fa68c87878e7f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b03166344e71c806040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fa191906159bf565b6137e0565b6000612fe487878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061420192505050565b9050612ff48d8a8a8e8e8661326d565b600061303288888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061421992505050565b90506130708a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506135ae92505050565b6001600160401b031661308a6130858f615883565b614231565b6001600160401b03161061314257603354600084815260366020908152604091829020825160808101845281546001600160401b038082168352600160401b8204811694830194909452600160801b81049093169381019390935261313793869388938a936001600160a01b03909316928892916060830190600160c01b900460ff16600281111561311e5761311e614d78565b600281111561312f5761312f614d78565b905250614243565b95505050505061315c565b60335461313790839086906001600160a01b031684614481565b5098975050505050505050565b603354604051633036cd5360e21b81526001600160a01b03918216600482015283821660248201527f0000000000000000000000002279b7a0a67db372996a5fab50d91eaa73d2ebe69091169063c0db354c9083906044016000604051808303818588803b1580156131da57600080fd5b505af11580156131ee573d6000803e3d6000fd5b50505050505050565b60008361320586858561455f565b1495945050505050565b60008160008151811061322457613224615456565b60200260200101519050919050565b60008160018151811061322457613224615456565b6000610c658260028151811061326057613260615456565b60200260200101516146ab565b61327960036002615ac0565b84146133045760405162461bcd60e51b815260206004820152604e60248201527f426561636f6e436861696e50726f6f66732e76657269667956616c696461746f60448201527f724669656c64733a2056616c696461746f72206669656c64732068617320696e60648201526d0c6dee4e4cac6e840d8cadccee8d60931b608482015260a4016106a4565b600561331260286001614b56565b61331c9190614b56565b613327906020615779565b82146133a75760405162461bcd60e51b815260206004820152604360248201527f426561636f6e436861696e50726f6f66732e76657269667956616c696461746f60448201527f724669656c64733a2050726f6f662068617320696e636f7272656374206c656e6064820152620cee8d60eb1b608482015260a4016106a4565b600064ffffffffff82166133bd60286001614b56565b600b901b179050600061340287878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061471292505050565b905061344885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508591508690506131f7565b6134ba5760405162461bcd60e51b815260206004820152603d60248201527f426561636f6e436861696e50726f6f66732e76657269667956616c696461746f60448201527f724669656c64733a20496e76616c6964206d65726b6c652070726f6f6600000060648201526084016106a4565b5050505050505050565b60007f000000000000000000000000000000000000000000000000000000006059f4606001600160401b0316826001600160401b0316101561356e5760405162461bcd60e51b815260206004820152603760248201527f456967656e506f642e5f74696d657374616d70546f45706f63683a2074696d6560448201527f7374616d70206973206265666f72652067656e6573697300000000000000000060648201526084016106a4565b61357a600c6020615acc565b6135a47f000000000000000000000000000000000000000000000000000000006059f46084615730565b610c659190615afb565b6000610c658260078151811061326057613260615456565b60006135de6001600160401b03808416908516615b21565b9392505050565b804710156136355760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016106a4565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613682576040519150601f19603f3d011682016040523d82523d6000602084013e613687565b606091505b505090508061162a5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016106a4565b6000613753826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166149bf9092919063ffffffff16565b80519091501561162a5780806020019051810190613771919061524e565b61162a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016106a4565b6000610c658261014001516146ab565b6137eb600280615ac0565b831461385f5760405162461bcd60e51b81526020600482015260496024820152600080516020615bd383398151915260448201527f616c3a207769746864726177616c4669656c64732068617320696e636f7272656064820152680c6e840d8cadccee8d60bb1b608482015260a4016106a4565b61386b600d6002615ac0565b61387b60c0840160a08501615b60565b6001600160401b0316106138e55760405162461bcd60e51b815260206004820152603f6024820152600080516020615bd383398151915260448201527f616c3a20626c6f636b526f6f74496e64657820697320746f6f206c617267650060648201526084016106a4565b6138f160046002615ac0565b613902610100840160e08501615b60565b6001600160401b03161061396e576040805162461bcd60e51b8152602060048201526024810191909152600080516020615bd383398151915260448201527f616c3a207769746864726177616c496e64657820697320746f6f206c6172676560648201526084016106a4565b61397a60186002615ac0565b61398a60e0840160c08501615b60565b6001600160401b031610613a045760405162461bcd60e51b81526020600482015260476024820152600080516020615bd383398151915260448201527f616c3a20686973746f726963616c53756d6d617279496e64657820697320746f6064820152666f206c6172676560c81b608482015260a4016106a4565b60006001600160401b038216613a1c612c9d85615883565b6001600160401b031610613a31576005613a34565b60045b9050613a41600482614b56565b613a4c906001614b56565b613a57906020615779565b613a618480615410565b905014613ad55760405162461bcd60e51b81526020600482015260486024820152600080516020615bd383398151915260448201527f616c3a207769746864726177616c50726f6f662068617320696e636f727265636064820152670e840d8cadccee8d60c31b608482015260a4016106a4565b613ae160046003614b56565b613aec906020615779565b613af96040850185615410565b905014613b735760405162461bcd60e51b815260206004820152604e6024820152600080516020615bd383398151915260448201527f616c3a20657865637574696f6e5061796c6f616450726f6f662068617320696e60648201526d0c6dee4e4cac6e840d8cadccee8d60931b608482015260a4016106a4565b613b7f60036020615779565b613b8c6020850185615410565b905014613bfa5760405162461bcd60e51b81526020600482015260426024820152600080516020615bd383398151915260448201527f616c3a20736c6f7450726f6f662068617320696e636f7272656374206c656e676064820152610e8d60f31b608482015260a4016106a4565b613c05816020615779565b613c126060850185615410565b905014613c855760405162461bcd60e51b81526020600482015260476024820152600080516020615bd383398151915260448201527f616c3a2074696d657374616d7050726f6f662068617320696e636f7272656374606482015266040d8cadccee8d60cb1b608482015260a4016106a4565b600d613c9360186001614b56565b613c9e906005614b56565b613ca9906001614b56565b613cb39190614b56565b613cbe906020615779565b613ccb6080850185615410565b905014613d545760405162461bcd60e51b81526020600482015260586024820152600080516020615bd383398151915260448201527f616c3a20686973746f726963616c53756d6d617279426c6f636b526f6f74507260648201527f6f6f662068617320696e636f7272656374206c656e6774680000000000000000608482015260a4016106a4565b6000613d6660c0850160a08601615b60565b6001600160401b03166000613d7d600d6001614b56565b613d8d60e0880160c08901615b60565b6001600160401b0316901b600d613da660186001614b56565b613db1906001614b56565b613dbb9190614b56565b601b901b1717179050613e16613dd46080860186615410565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92505050610100870135846131f7565b613e895760405162461bcd60e51b815260206004820152604a6024820152600080516020615bd383398151915260448201527f616c3a20496e76616c696420686973746f726963616c73756d6d617279206d656064820152693935b63290383937b7b360b11b608482015260a4016106a4565b613ee0613e996020860186615410565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506101008a013593506101208a0135925090506131f7565b613f405760405162461bcd60e51b815260206004820152603d6024820152600080516020615bd383398151915260448201527f616c3a20496e76616c696420736c6f74206d65726b6c652070726f6f6600000060648201526084016106a4565b6049613f98613f526040870187615410565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505050610100870135610160880135846131f7565b61400a5760405162461bcd60e51b81526020600482015260496024820152600080516020615bd383398151915260448201527f616c3a20496e76616c696420657865637574696f6e5061796c6f6164206d657260648201526835b63290383937b7b360b91b608482015260a4016106a4565b5061406261401b6060860186615410565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505061016086013561014087013560096131f7565b6140cd5760405162461bcd60e51b81526020600482015260426024820152600080516020615bd383398151915260448201527f616c3a20496e76616c69642074696d657374616d70206d65726b6c652070726f60648201526137b360f11b608482015260a4016106a4565b60006140e0610100860160e08701615b60565b6001600160401b03166140f560046001614b56565b600e901b179050600061413a88888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061471292505050565b905061418a6141498780615410565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505061016088013583856131f7565b6141f65760405162461bcd60e51b81526020600482015260436024820152600080516020615bd383398151915260448201527f616c3a20496e76616c6964207769746864726177616c206d65726b6c6520707260648201526237b7b360e91b608482015260a4016106a4565b505050505050505050565b6000610c658260018151811061326057613260615456565b6000610c658260038151811061326057613260615456565b600060206135a48361012001516146ab565b604080518082019091526000808252602082015260007f00000000000000000000000000000000000000000000000000000007735940006001600160401b0316846001600160401b031611156142ba57507f00000000000000000000000000000000000000000000000000000007735940006142bd565b50825b60408051808201909152600080825260208201526142db8286615730565b6001600160401b0390811682526034805484926000916142fd91859116615b7d565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555061432f8285602001516135c6565b602082015260028460600151600281111561434c5761434c614d78565b1461436e576039805490600061436183615ba8565b9091555050600260608501525b600060208086018281528a83526036909152604091829020865181549251938801516001600160401b03908116600160801b0267ffffffffffffffff60801b19958216600160401b026001600160801b0319909516929091169190911792909217928316821781556060870151879391929091839160ff60c01b191668ffffffffffffffffff60801b1990911617600160c01b83600281111561441357614413614d78565b0217905550506040805164ffffffffff8c1681526001600160401b038a8116602083015288168183015290516001600160a01b03891692507fb76a93bb649ece524688f1a01d184e0bbebcda58eae80c28a898bec3fb5a09639181900360600190a298975050505050505050565b60408051808201909152600080825260208201526040805164ffffffffff871681526001600160401b0380871660208301528416918101919091526001600160a01b038416907f8a7335714231dbd551aaba6314f4a97a14c201e53a3e25e1140325cdf67d7a4e9060600160405180910390a2603880548391906000906145129084906001600160401b0316615b7d565b92506101000a8154816001600160401b0302191690836001600160401b031602179055506040518060400160405280836001600160401b0316815260200160008152509050949350505050565b6000835160001415801561457e57506020845161457c9190615708565b155b61460d5760405162461bcd60e51b815260206004820152605460248201527f4d65726b6c652e70726f63657373496e636c7573696f6e50726f6f665368613260448201527f35363a2070726f6f66206c656e6774682073686f756c642062652061206e6f6e60648201527316bd32b9379036bab63a34b836329037b310199960611b608482015260a4016106a4565b604080516020808201909252848152905b855181116146a157614631600285615708565b614664578151600052808601516020526020826040600060026107d05a03fa61465957600080fd5b60028404935061468f565b8086015160005281516020526020826040600060026107d05a03fa61468857600080fd5b6002840493505b61469a602082614b56565b905061461e565b5051949350505050565b60f881901c60e882901c61ff00161760d882901c62ff0000161760c882901c63ff000000161764ff0000000060b883901c161765ff000000000060a883901c161766ff000000000000609883901c161767ff0000000000000060889290921c919091161790565b60008060028351614723919061571c565b90506000816001600160401b0381111561473f5761473f614f85565b604051908082528060200260200182016040528015614768578160200160208202803683370190505b50905060005b8281101561486f576002856147838383615779565b8151811061479357614793615456565b6020026020010151868360026147a99190615779565b6147b4906001614b56565b815181106147c4576147c4615456565b60200260200101516040516020016147e6929190918252602082015260400190565b60408051601f198184030181529082905261480091615802565b602060405180830381855afa15801561481d573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061484091906153f7565b82828151811061485257614852615456565b602090810291909101015280614867816154dc565b91505061476e565b5061487b60028361571c565b91505b811561499b5760005b828110156149885760028261489c8383615779565b815181106148ac576148ac615456565b6020026020010151838360026148c29190615779565b6148cd906001614b56565b815181106148dd576148dd615456565b60200260200101516040516020016148ff929190918252602082015260400190565b60408051601f198184030181529082905261491991615802565b602060405180830381855afa158015614936573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061495991906153f7565b82828151811061496b5761496b615456565b602090810291909101015280614980816154dc565b915050614887565b5061499460028361571c565b915061487e565b806000815181106149ae576149ae615456565b602002602001015192505050919050565b60606149ce84846000856149d6565b949350505050565b606082471015614a375760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016106a4565b6001600160a01b0385163b614a8e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106a4565b600080866001600160a01b03168587604051614aaa9190615802565b60006040518083038185875af1925050503d8060008114614ae7576040519150601f19603f3d011682016040523d82523d6000602084013e614aec565b606091505b5091509150614afc828286614b07565b979650505050505050565b60608315614b165750816135de565b825115614b265782518084602001fd5b8160405162461bcd60e51b81526004016106a49190615bbf565b634e487b7160e01b600052601160045260246000fd5b60008219821115614b6957614b69614b40565b500190565b6001600160401b0381168114611fb957600080fd5b8035614b8e81614b6e565b919050565b60008060408385031215614ba657600080fd5b823591506020830135614bb881614b6e565b809150509250929050565b600060408284031215614bd557600080fd5b50919050565b60008083601f840112614bed57600080fd5b5081356001600160401b03811115614c0457600080fd5b6020830191508360208260051b8501011115614c1f57600080fd5b9250929050565b60008060008060008060008060a0898b031215614c4257600080fd5b8835614c4d81614b6e565b975060208901356001600160401b0380821115614c6957600080fd5b614c758c838d01614bc3565b985060408b0135915080821115614c8b57600080fd5b614c978c838d01614bdb565b909850965060608b0135915080821115614cb057600080fd5b614cbc8c838d01614bdb565b909650945060808b0135915080821115614cd557600080fd5b50614ce28b828c01614bdb565b999c989b5096995094979396929594505050565b60008083601f840112614d0857600080fd5b5081356001600160401b03811115614d1f57600080fd5b602083019150836020828501011115614c1f57600080fd5b60008060208385031215614d4a57600080fd5b82356001600160401b03811115614d6057600080fd5b614d6c85828601614cf6565b90969095509350505050565b634e487b7160e01b600052602160045260246000fd5b60038110614dac57634e487b7160e01b600052602160045260246000fd5b9052565b60208101610c658284614d8e565b600060208284031215614dd057600080fd5b5035919050565b60006080820190506001600160401b03808451168352806020850151166020840152806040850151166040840152506060830151614e186060840182614d8e565b5092915050565b600080600080600060608688031215614e3757600080fd5b85356001600160401b0380821115614e4e57600080fd5b614e5a89838a01614cf6565b90975095506020880135915080821115614e7357600080fd5b50614e8088828901614cf6565b96999598509660400135949350505050565b60008060008060008060008060a0898b031215614eae57600080fd5b8835614eb981614b6e565b975060208901356001600160401b0380821115614ed557600080fd5b614ee18c838d01614bdb565b909950975060408b0135915080821115614efa57600080fd5b614f068c838d01614bc3565b965060608b0135915080821115614cb057600080fd5b6001600160a01b0381168114611fb957600080fd5b8035614b8e81614f1c565b60008060408385031215614f4f57600080fd5b8235614f5a81614f1c565b946020939093013593505050565b600060208284031215614f7a57600080fd5b81356135de81614f1c565b634e487b7160e01b600052604160045260246000fd5b60405161018081016001600160401b0381118282101715614fbe57614fbe614f85565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614fec57614fec614f85565b604052919050565b60006001600160401b0382111561500d5761500d614f85565b5060051b60200190565b600082601f83011261502857600080fd5b8135602061503d61503883614ff4565b614fc4565b82815260059290921b8401810191818101908684111561505c57600080fd5b8286015b848110156150775780358352918301918301615060565b509695505050505050565b60008060006060848603121561509757600080fd5b83356001600160401b03808211156150ae57600080fd5b818601915086601f8301126150c257600080fd5b813560206150d261503883614ff4565b82815260059290921b8401810191818101908a8411156150f157600080fd5b948201945b8386101561511857853561510981614f1c565b825294820194908201906150f6565b9750508701359250508082111561512e57600080fd5b5061513b86828701615017565b92505061514a60408501614f31565b90509250925092565b60008060008060008060008060008060c08b8d03121561517257600080fd5b61517b8b614b83565b995060208b01356001600160401b038082111561519757600080fd5b6151a38e838f01614bc3565b9a5060408d01359150808211156151b957600080fd5b6151c58e838f01614bdb565b909a50985060608d01359150808211156151de57600080fd5b6151ea8e838f01614bdb565b909850965060808d013591508082111561520357600080fd5b61520f8e838f01614bdb565b909650945060a08d013591508082111561522857600080fd5b506152358d828e01614bdb565b915080935050809150509295989b9194979a5092959850565b60006020828403121561526057600080fd5b815180151581146135de57600080fd5b6020808252603e908201527f456967656e506f642e6f6e6c795768656e4e6f745061757365643a20696e646560408201527f782069732070617573656420696e20456967656e506f644d616e616765720000606082015260800190565b60208082526028908201527f456967656e506f642e6f6e6c79456967656e506f644f776e65723a206e6f74206040820152673837b227bbb732b960c11b606082015260800190565b6020808252602f908201527f456967656e506f642e6861734e6576657252657374616b65643a20726573746160408201526e1ada5b99c81a5cc8195b98589b1959608a1b606082015260800190565b60208082526067908201527f456967656e506f642e70726f6f664973466f7256616c696454696d657374616d60408201527f703a20626561636f6e20636861696e2070726f6f66206d75737420626520617460608201527f206f72206166746572206d6f7374526563656e745769746864726177616c546960808201526606d657374616d760cc1b60a082015260c00190565b60006020828403121561540957600080fd5b5051919050565b6000808335601e1984360301811261542757600080fd5b8301803591506001600160401b0382111561544157600080fd5b602001915036819003821315614c1f57600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561547e57600080fd5b813564ffffffffff811681146135de57600080fd5b6000808335601e198436030181126154aa57600080fd5b8301803591506001600160401b038211156154c457600080fd5b6020019150600581901b3603821315614c1f57600080fd5b60006000198214156154f0576154f0614b40565b5060010190565b60208082526031908201527f456967656e506f642e6f6e6c79456967656e506f644d616e616765723a206e6f6040820152703a1032b4b3b2b72837b226b0b730b3b2b960791b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60005b8381101561558c578181015183820152602001615574565b838111156121445750506000910152565b600081518084526155b5816020860160208601615571565b601f01601f19169290920160200192915050565b6080815260006155dd60808301888a615548565b82810360208401526155ef818861559d565b90508281036040840152615604818688615548565b915050826060830152979650505050505050565b6020815260006149ce602083018486615548565b600080821280156001600160ff1b038490038513161561564e5761564e614b40565b600160ff1b839003841281161561566757615667614b40565b50500190565b60006001600160ff1b038184138284138082168684048611161561569357615693614b40565b600160ff1b60008712828116878305891216156156b2576156b2614b40565b600087129250878205871284841616156156ce576156ce614b40565b878505871281841616156156e4576156e4614b40565b505050929093029392505050565b634e487b7160e01b600052601260045260246000fd5b600082615717576157176156f2565b500690565b60008261572b5761572b6156f2565b500490565b60006001600160401b038381169083168181101561575057615750614b40565b039392505050565b6000823561017e1983360301811261576f57600080fd5b9190910192915050565b600081600019048311821515161561579357615793614b40565b500290565b6000828210156157aa576157aa614b40565b500390565b80516020808301519190811015614bd55760001960209190910360031b1b16919050565b600083516157e5818460208801615571565b6001600160801b0319939093169190920190815260100192915050565b6000825161576f818460208701615571565b600082601f83011261582557600080fd5b81356001600160401b0381111561583e5761583e614f85565b615851601f8201601f1916602001614fc4565b81815284602083860101111561586657600080fd5b816020850160208301376000918101602001919091529392505050565b6000610180823603121561589657600080fd5b61589e614f9b565b82356001600160401b03808211156158b557600080fd5b6158c136838701615814565b835260208501359150808211156158d757600080fd5b6158e336838701615814565b602084015260408501359150808211156158fc57600080fd5b61590836838701615814565b6040840152606085013591508082111561592157600080fd5b61592d36838701615814565b6060840152608085013591508082111561594657600080fd5b5061595336828601615814565b60808301525061596560a08401614b83565b60a082015261597660c08401614b83565b60c082015261598760e08401614b83565b60e082015261010083810135908201526101208084013590820152610140808401359082015261016092830135928101929092525090565b6000602082840312156159d157600080fd5b81516135de81614b6e565b600181815b80851115615a175781600019048211156159fd576159fd614b40565b80851615615a0a57918102915b93841c93908002906159e1565b509250929050565b600082615a2e57506001610c65565b81615a3b57506000610c65565b8160018114615a515760028114615a5b57615a77565b6001915050610c65565b60ff841115615a6c57615a6c614b40565b50506001821b610c65565b5060208310610133831016604e8410600b8410161715615a9a575081810a610c65565b615aa483836159dc565b8060001904821115615ab857615ab8614b40565b029392505050565b60006135de8383615a1f565b60006001600160401b0380831681851681830481118215151615615af257615af2614b40565b02949350505050565b60006001600160401b0380841680615b1557615b156156f2565b92169190910492915050565b60008083128015600160ff1b850184121615615b3f57615b3f614b40565b6001600160ff1b0384018313811615615b5a57615b5a614b40565b50500390565b600060208284031215615b7257600080fd5b81356135de81614b6e565b60006001600160401b03808316818516808303821115615b9f57615b9f614b40565b01949350505050565b600081615bb757615bb7614b40565b506000190190565b6020815260006135de602083018461559d56fe426561636f6e436861696e50726f6f66732e7665726966795769746864726177a264697066735822122028632f0badb0d5a48e7147a2a4a101d592d417e2a3f16ef6718f13f04f32109264736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x90f79bf6eb2c4f870365e785982e1f101e93b906":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x95401dc811bb5740090279ba06cfa8fcf6113778":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80633563b0d1146100515780634f739f741461007a5780635c1556621461009a578063cefdc1d4146100ba575b600080fd5b61006461005f366004611172565b6100db565b60405161007191906112cd565b60405180910390f35b61008d610088366004611332565b610571565b6040516100719190611435565b6100ad6100a8366004611513565b610c9b565b60405161007191906115c4565b6100cd6100c8366004611608565b610e63565b60405161007192919061164a565b60606000846001600160a01b031663683048356040518163ffffffff1660e01b8152600401602060405180830381865afa15801561011d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610141919061166b565b90506000856001600160a01b0316639e9923c26040518163ffffffff1660e01b8152600401602060405180830381865afa158015610183573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101a7919061166b565b90506000866001600160a01b0316635df459466040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061020d919061166b565b9050600086516001600160401b0381111561022a5761022a61110a565b60405190808252806020026020018201604052801561025d57816020015b60608152602001906001900390816102485790505b50905060005b875181101561056557600088828151811061028057610280611688565b0160200151604051638902624560e01b815260f89190911c6004820181905263ffffffff8a16602483015291506000906001600160a01b03871690638902624590604401600060405180830381865afa1580156102e1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610309919081019061169e565b905080516001600160401b038111156103245761032461110a565b60405190808252806020026020018201604052801561036f57816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816103425790505b5084848151811061038257610382611688565b602002602001018190525060005b815181101561054f576040518060600160405280876001600160a01b03166347b314e88585815181106103c5576103c5611688565b60200260200101516040518263ffffffff1660e01b81526004016103eb91815260200190565b602060405180830381865afa158015610408573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042c919061166b565b6001600160a01b0316815260200183838151811061044c5761044c611688565b60200260200101518152602001896001600160a01b031663fa28c62785858151811061047a5761047a611688565b60209081029190910101516040516001600160e01b031960e084901b168152600481019190915260ff8816602482015263ffffffff8f166044820152606401602060405180830381865afa1580156104d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104fa919061172e565b6001600160601b031681525085858151811061051857610518611688565b6020026020010151828151811061053157610531611688565b602002602001018190525080806105479061176d565b915050610390565b505050808061055d9061176d565b915050610263565b50979650505050505050565b61059c6040518060800160405280606081526020016060815260200160608152602001606081525090565b6000876001600160a01b031663683048356040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610600919061166b565b905061062d6040518060800160405280606081526020016060815260200160608152602001606081525090565b6040516361c8a12f60e11b81526001600160a01b038a169063c391425e9061065d908b9089908990600401611788565b600060405180830381865afa15801561067a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526106a291908101906117d2565b81526040516340e03a8160e11b81526001600160a01b038316906381c07502906106d4908b908b908b90600401611889565b600060405180830381865afa1580156106f1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261071991908101906117d2565b6040820152856001600160401b038111156107365761073661110a565b60405190808252806020026020018201604052801561076957816020015b60608152602001906001900390816107545790505b50606082015260005b60ff8116871115610bac576000856001600160401b038111156107975761079761110a565b6040519080825280602002602001820160405280156107c0578160200160208202803683370190505b5083606001518360ff16815181106107da576107da611688565b602002602001018190525060005b86811015610aac5760008c6001600160a01b03166304ec63518a8a8581811061081357610813611688565b905060200201358e8860000151868151811061083157610831611688565b60200260200101516040518463ffffffff1660e01b815260040161086e9392919092835263ffffffff918216602084015216604082015260600190565b602060405180830381865afa15801561088b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108af91906118b2565b90506001600160c01b0381166109575760405162461bcd60e51b815260206004820152605c60248201527f4f70657261746f7253746174655265747269657665722e676574436865636b5360448201527f69676e617475726573496e64696365733a206f70657261746f72206d7573742060648201527f6265207265676973746572656420617420626c6f636b6e756d62657200000000608482015260a40160405180910390fd5b8a8a8560ff1681811061096c5761096c611688565b6001600160c01b03841692013560f81c9190911c600190811614159050610a9957856001600160a01b031663dd9846b98a8a858181106109ae576109ae611688565b905060200201358d8d8860ff168181106109ca576109ca611688565b6040516001600160e01b031960e087901b1681526004810194909452919091013560f81c60248301525063ffffffff8f166044820152606401602060405180830381865afa158015610a20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4491906118db565b85606001518560ff1681518110610a5d57610a5d611688565b60200260200101518481518110610a7657610a76611688565b63ffffffff9092166020928302919091019091015282610a958161176d565b9350505b5080610aa48161176d565b9150506107e8565b506000816001600160401b03811115610ac757610ac761110a565b604051908082528060200260200182016040528015610af0578160200160208202803683370190505b50905060005b82811015610b715784606001518460ff1681518110610b1757610b17611688565b60200260200101518181518110610b3057610b30611688565b6020026020010151828281518110610b4a57610b4a611688565b63ffffffff9092166020928302919091019091015280610b698161176d565b915050610af6565b508084606001518460ff1681518110610b8c57610b8c611688565b602002602001018190525050508080610ba4906118f8565b915050610772565b506000896001600160a01b0316635df459466040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c11919061166b565b60405163354952a360e21b81529091506001600160a01b0382169063d5254a8c90610c44908b908b908e90600401611918565b600060405180830381865afa158015610c61573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c8991908101906117d2565b60208301525098975050505050505050565b60606000846001600160a01b031663c391425e84866040518363ffffffff1660e01b8152600401610ccd929190611942565b600060405180830381865afa158015610cea573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d1291908101906117d2565b9050600084516001600160401b03811115610d2f57610d2f61110a565b604051908082528060200260200182016040528015610d58578160200160208202803683370190505b50905060005b8551811015610e5957866001600160a01b03166304ec6351878381518110610d8857610d88611688565b602002602001015187868581518110610da357610da3611688565b60200260200101516040518463ffffffff1660e01b8152600401610de09392919092835263ffffffff918216602084015216604082015260600190565b602060405180830381865afa158015610dfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2191906118b2565b6001600160c01b0316828281518110610e3c57610e3c611688565b602090810291909101015280610e518161176d565b915050610d5e565b5095945050505050565b6040805160018082528183019092526000916060918391602080830190803683370190505090508481600081518110610e9e57610e9e611688565b60209081029190910101526040516361c8a12f60e11b81526000906001600160a01b0388169063c391425e90610eda9088908690600401611942565b600060405180830381865afa158015610ef7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f1f91908101906117d2565b600081518110610f3157610f31611688565b60209081029190910101516040516304ec635160e01b81526004810188905263ffffffff87811660248301529091166044820181905291506000906001600160a01b038916906304ec635190606401602060405180830381865afa158015610f9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc191906118b2565b6001600160c01b031690506000610fd782610ff5565b905081610fe58a838a6100db565b9550955050505050935093915050565b6060600080611003846110c1565b61ffff166001600160401b0381111561101e5761101e61110a565b6040519080825280601f01601f191660200182016040528015611048576020820181803683370190505b5090506000805b825182108015611060575061010081105b156110b7576001811b9350858416156110a7578060f81b83838151811061108957611089611688565b60200101906001600160f81b031916908160001a9053508160010191505b6110b08161176d565b905061104f565b5090949350505050565b6000805b82156110ec576110d6600184611996565b90921691806110e4816119ad565b9150506110c5565b92915050565b6001600160a01b038116811461110757600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156111485761114861110a565b604052919050565b63ffffffff8116811461110757600080fd5b803561116d81611150565b919050565b60008060006060848603121561118757600080fd5b8335611192816110f2565b92506020848101356001600160401b03808211156111af57600080fd5b818701915087601f8301126111c357600080fd5b8135818111156111d5576111d561110a565b6111e7601f8201601f19168501611120565b915080825288848285010111156111fd57600080fd5b808484018584013760008482840101525080945050505061122060408501611162565b90509250925092565b600081518084526020808501808196508360051b810191508286016000805b868110156112bf578385038a52825180518087529087019087870190845b818110156112aa57835180516001600160a01b031684528a8101518b8501526040908101516001600160601b03169084015292890192606090920191600101611266565b50509a87019a95505091850191600101611248565b509298975050505050505050565b6020815260006112e06020830184611229565b9392505050565b60008083601f8401126112f957600080fd5b5081356001600160401b0381111561131057600080fd5b6020830191508360208260051b850101111561132b57600080fd5b9250929050565b6000806000806000806080878903121561134b57600080fd5b8635611356816110f2565b9550602087013561136681611150565b945060408701356001600160401b038082111561138257600080fd5b818901915089601f83011261139657600080fd5b8135818111156113a557600080fd5b8a60208285010111156113b757600080fd5b6020830196508095505060608901359150808211156113d557600080fd5b506113e289828a016112e7565b979a9699509497509295939492505050565b600081518084526020808501945080840160005b8381101561142a57815163ffffffff1687529582019590820190600101611408565b509495945050505050565b60006020808352835160808285015261145160a08501826113f4565b905081850151601f198086840301604087015261146e83836113f4565b9250604087015191508086840301606087015261148b83836113f4565b60608801518782038301608089015280518083529194508501925084840190600581901b8501860160005b828110156114e257848783030184526114d08287516113f4565b958801959388019391506001016114b6565b509998505050505050505050565b60006001600160401b038211156115095761150961110a565b5060051b60200190565b60008060006060848603121561152857600080fd5b8335611533816110f2565b92506020848101356001600160401b0381111561154f57600080fd5b8501601f8101871361156057600080fd5b803561157361156e826114f0565b611120565b81815260059190911b8201830190838101908983111561159257600080fd5b928401925b828410156115b057833582529284019290840190611597565b809650505050505061122060408501611162565b6020808252825182820181905260009190848201906040850190845b818110156115fc578351835292840192918401916001016115e0565b50909695505050505050565b60008060006060848603121561161d57600080fd5b8335611628816110f2565b925060208401359150604084013561163f81611150565b809150509250925092565b8281526040602082015260006116636040830184611229565b949350505050565b60006020828403121561167d57600080fd5b81516112e0816110f2565b634e487b7160e01b600052603260045260246000fd5b600060208083850312156116b157600080fd5b82516001600160401b038111156116c757600080fd5b8301601f810185136116d857600080fd5b80516116e661156e826114f0565b81815260059190911b8201830190838101908783111561170557600080fd5b928401925b828410156117235783518252928401929084019061170a565b979650505050505050565b60006020828403121561174057600080fd5b81516001600160601b03811681146112e057600080fd5b634e487b7160e01b600052601160045260246000fd5b600060001982141561178157611781611757565b5060010190565b63ffffffff84168152604060208201819052810182905260006001600160fb1b038311156117b557600080fd5b8260051b8085606085013760009201606001918252509392505050565b600060208083850312156117e557600080fd5b82516001600160401b038111156117fb57600080fd5b8301601f8101851361180c57600080fd5b805161181a61156e826114f0565b81815260059190911b8201830190838101908783111561183957600080fd5b928401925b8284101561172357835161185181611150565b8252928401929084019061183e565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b63ffffffff841681526040602082015260006118a9604083018486611860565b95945050505050565b6000602082840312156118c457600080fd5b81516001600160c01b03811681146112e057600080fd5b6000602082840312156118ed57600080fd5b81516112e081611150565b600060ff821660ff81141561190f5761190f611757565b60010192915050565b60408152600061192c604083018587611860565b905063ffffffff83166020830152949350505050565b60006040820163ffffffff851683526020604081850152818551808452606086019150828701935060005b818110156119895784518352938301939183019160010161196d565b5090979650505050505050565b6000828210156119a8576119a8611757565b500390565b600061ffff808316818114156119c5576119c5611757565b600101939250505056fea2646970667358221220bf7da3ac19e822f668d6745bdefcbea2c8215c9fa36602d083423e9d7730b97364736f6c634300080c0033","storage":{}},"0x959922be3caee4b8cd9a407cc3ac1c251c2007b1":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061014b5760003560e01c806385594e58116100b6578063e4f4f8871161006f578063e4f4f887146103cc578063e5db06c014610405578063eb990c5914610425578063ecb7cb1b14610445578063f2fde38b14610472578063fabc1cbc1461049257600080fd5b806385594e5814610317578063886f1195146103445780638da5cb5b14610364578063c0db354c14610382578063ca661c0414610395578063d44e1b76146103ac57600080fd5b806350f73e7c1161010857806350f73e7c14610254578063595c6a67146102785780635ac86ab71461028d5780635c975abb146102cd578063715018a6146102e257806375608896146102f757600080fd5b806310d67a2f14610150578063136439dd146101725780631f39d87f146101925780633e1de008146101c85780634665bcda146101e85780634d50f9a414610234575b600080fd5b34801561015c57600080fd5b5061017061016b36600461196d565b6104b2565b005b34801561017e57600080fd5b5061017061018d366004611991565b61056e565b34801561019e57600080fd5b506101b26101ad36600461196d565b6106ad565b6040516101bf91906119c8565b60405180910390f35b3480156101d457600080fd5b506101b26101e336600461196d565b6108a8565b3480156101f457600080fd5b5061021c7f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85381565b6040516001600160a01b0390911681526020016101bf565b34801561024057600080fd5b5061017061024f366004611991565b6109ee565b34801561026057600080fd5b5061026a60c95481565b6040519081526020016101bf565b34801561028457600080fd5b506101706109ff565b34801561029957600080fd5b506102bd6102a8366004611a15565b609854600160ff9092169190911b9081161490565b60405190151581526020016101bf565b3480156102d957600080fd5b5060985461026a565b3480156102ee57600080fd5b50610170610ac6565b34801561030357600080fd5b506102bd610312366004611a38565b610ada565b34801561032357600080fd5b50610337610332366004611a38565b610b5d565b6040516101bf9190611a64565b34801561035057600080fd5b5060975461021c906001600160a01b031681565b34801561037057600080fd5b506033546001600160a01b031661021c565b610170610390366004611a72565b610bdd565b3480156103a157600080fd5b5061026a62034bc081565b3480156103b857600080fd5b506101706103c7366004611991565b610e9d565b3480156103d857600080fd5b5061026a6103e736600461196d565b6001600160a01b0316600090815260ca602052604090206001015490565b34801561041157600080fd5b50610170610420366004611a38565b610f31565b34801561043157600080fd5b50610170610440366004611aab565b610fc6565b34801561045157600080fd5b5061046561046036600461196d565b6110ee565b6040516101bf9190611af1565b34801561047e57600080fd5b5061017061048d36600461196d565b6111a8565b34801561049e57600080fd5b506101706104ad366004611991565b61121e565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610505573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105299190611b47565b6001600160a01b0316336001600160a01b0316146105625760405162461bcd60e51b815260040161055990611b64565b60405180910390fd5b61056b8161137a565b50565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156105b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105da9190611bae565b6105f65760405162461bcd60e51b815260040161055990611bd0565b6098548181161461066f5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610559565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6001600160a01b038116600090815260ca6020526040812080546001909101546060926106da8383611c2e565b90508060005b82811015610786576001600160a01b038716600090815260ca6020526040812060010161070d8388611c45565b8154811061071d5761071d611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff1691810182905260c95490925061076391611c45565b4310156107735781925050610786565b508061077e81611c73565b9150506106e0565b508060008167ffffffffffffffff8111156107a3576107a3611c8e565b6040519080825280602002602001820160405280156107e857816020015b60408051808201909152600080825260208201528152602001906001900390816107c15790505b509050811561089d5760005b8281101561089b576001600160a01b038916600090815260ca602052604090206001016108218289611c45565b8154811061083157610831611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff1691810191909152825183908390811061087d5761087d611c5d565b6020026020010181905250808061089390611c73565b9150506107f4565b505b979650505050505050565b6001600160a01b038116600090815260ca6020526040812080546001909101546060926108d58383611c2e565b905060008167ffffffffffffffff8111156108f2576108f2611c8e565b60405190808252806020026020018201604052801561093757816020015b60408051808201909152600080825260208201528152602001906001900390816109105790505b50905060005b828110156109e4576001600160a01b038716600090815260ca6020526040902060010161096a8287611c45565b8154811061097a5761097a611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff169181019190915282518390839081106109c6576109c6611c5d565b602002602001018190525080806109dc90611c73565b91505061093d565b5095945050505050565b6109f6611471565b61056b816114cb565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610a47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6b9190611bae565b610a875760405162461bcd60e51b815260040161055990611bd0565b600019609881905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b610ace611471565b610ad86000611593565b565b6001600160a01b038216600090815260ca60205260408120548210801590610b54575060c9546001600160a01b038416600090815260ca60205260409020600101805484908110610b2d57610b2d611c5d565b600091825260209091200154610b509190600160e01b900463ffffffff16611c45565b4310155b90505b92915050565b60408051808201909152600080825260208201526001600160a01b038316600090815260ca60205260409020600101805483908110610b9e57610b9e611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff16918101919091529392505050565b60405163a38406a360e01b81526001600160a01b038084166004830152839133917f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c853169063a38406a390602401602060405180830381865afa158015610c47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6b9190611b47565b6001600160a01b031614610ce75760405162461bcd60e51b815260206004820152603d60248201527f44656c617965645769746864726177616c526f757465722e6f6e6c794569676560448201527f6e506f643a206e6f7420706f644f776e6572277320456967656e506f640000006064820152608401610559565b60985460009060019081161415610d105760405162461bcd60e51b815260040161055990611ca4565b6001600160a01b038316610da65760405162461bcd60e51b815260206004820152605160248201527f44656c617965645769746864726177616c526f757465722e637265617465446560448201527f6c617965645769746864726177616c3a20726563697069656e742063616e6e6f60648201527074206265207a65726f206164647265737360781b608482015260a401610559565b346001600160e01b03811615610e96576040805180820182526001600160e01b03808416825263ffffffff43811660208085019182526001600160a01b038a16600081815260ca8352968720600190810180548083018255818a5293892088519551909616600160e01b029490961693909317939091019290925593525490917fb8f1b14c7caf74150801dcc9bc18d575cbeaf5b421943497e409df92c92e0f5991889188918691610e5791611c2e565b604080516001600160a01b0395861681529490931660208501526001600160e01b039091169183019190915260608201526080015b60405180910390a1505b5050505050565b60026065541415610ef05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610559565b600260655560985460009060019081161415610f1e5760405162461bcd60e51b815260040161055990611ca4565b610f2833836115e5565b50506001606555565b60026065541415610f845760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610559565b600260655560985460009060019081161415610fb25760405162461bcd60e51b815260040161055990611ca4565b610fbc83836115e5565b5050600160655550565b600054610100900460ff1615808015610fe65750600054600160ff909116105b806110005750303b158015611000575060005460ff166001145b6110635760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610559565b6000805460ff191660011790558015611086576000805461ff0019166101001790555b61108f85611593565b6110998484611750565b6110a2826114cb565b8015610e96576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6040805180820190915260008152606060208201526001600160a01b038216600090815260ca6020908152604080832081518083018352815481526001820180548451818702810187019095528085529195929486810194939192919084015b8282101561119a57600084815260209081902060408051808201909152908401546001600160e01b0381168252600160e01b900463ffffffff168183015282526001909201910161114e565b505050915250909392505050565b6111b0611471565b6001600160a01b0381166112155760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610559565b61056b81611593565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611271573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112959190611b47565b6001600160a01b0316336001600160a01b0316146112c55760405162461bcd60e51b815260040161055990611b64565b6098541981196098541916146113435760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610559565b609881905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c906020016106a2565b6001600160a01b0381166114085760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610559565b609754604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1609780546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b03163314610ad85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610559565b62034bc08111156115525760405162461bcd60e51b815260206004820152604560248201527f44656c617965645769746864726177616c526f757465722e5f7365745769746860448201527f64726177616c44656c6179426c6f636b733a206e657756616c756520746f6f206064820152646c6172676560d81b608482015260a401610559565b60c95460408051918252602082018390527f4ffb00400574147429ee377a5633386321e66d45d8b14676014b5fa393e61e9e910160405180910390a160c955565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038216600090815260ca602052604081208054600190910154825b848110801561161e57508161161c8285611c45565b105b156116cb576001600160a01b038616600090815260ca602052604081206001016116488386611c45565b8154811061165857611658611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff1691810182905260c95490925061169e91611c45565b4310156116ab57506116cb565b80516116c0906001600160e01b031686611c45565b945050600101611607565b6116d58184611c45565b6001600160a01b038716600090815260ca602052604090205583156116fe576116fe868561183a565b7f6b7151500bd0b5cc211bcc47b3029831b769004df4549e8e1c9a69da05bb0943868561172b8487611c45565b604080516001600160a01b039094168452602084019290925290820152606001610e8c565b6097546001600160a01b031615801561177157506001600160a01b03821615155b6117f35760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610559565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a26118368261137a565b5050565b8047101561188a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610559565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146118d7576040519150601f19603f3d011682016040523d82523d6000602084013e6118dc565b606091505b50509050806119535760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610559565b505050565b6001600160a01b038116811461056b57600080fd5b60006020828403121561197f57600080fd5b813561198a81611958565b9392505050565b6000602082840312156119a357600080fd5b5035919050565b80516001600160e01b0316825260209081015163ffffffff16910152565b602080825282518282018190526000919060409081850190868401855b82811015611a08576119f88483516119aa565b92840192908501906001016119e5565b5091979650505050505050565b600060208284031215611a2757600080fd5b813560ff8116811461198a57600080fd5b60008060408385031215611a4b57600080fd5b8235611a5681611958565b946020939093013593505050565b60408101610b5782846119aa565b60008060408385031215611a8557600080fd5b8235611a9081611958565b91506020830135611aa081611958565b809150509250929050565b60008060008060808587031215611ac157600080fd5b8435611acc81611958565b93506020850135611adc81611958565b93969395505050506040820135916060013590565b602080825282518282015282810151604080840181905281516060850181905260009392830191849160808701905b8084101561089b57611b338286516119aa565b938501936001939093019290820190611b20565b600060208284031215611b5957600080fd5b815161198a81611958565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215611bc057600080fd5b8151801515811461198a57600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082821015611c4057611c40611c18565b500390565b60008219821115611c5857611c58611c18565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415611c8757611c87611c18565b5060010190565b634e487b7160e01b600052604160045260246000fd5b60208082526019908201527f5061757361626c653a20696e646578206973207061757365640000000000000060408201526060019056fea264697066735822122028be5fb1babf5ce64b9eafb2fd380ed51a13f09dc7861d1336f53e4f39e35e0f64736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x976ea74026e726554db657fa54763abd0c3a0aa9":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x998abeb3e57409262ae5b751f60747921b33613e":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106101e55760003560e01c80639f3ccf651161010f578063c8294c56116100a2578063f2be94ae11610071578063f2be94ae1461054b578063f851e1981461055e578063fa28c62714610571578063ff694a771461058457600080fd5b8063c8294c56146104d6578063d5eccc05146104e9578063dd9846b9146104fc578063df5cf7231461052457600080fd5b8063bc9a40c3116100de578063bc9a40c314610474578063bd29b8cd14610487578063c46778a51461049a578063c601527d146104c357600080fd5b80639f3ccf65146103ee578063ac6bfb0314610401578063adc804da14610421578063b6904b781461046157600080fd5b80634bd26e091161018757806366acfefe1161015657806366acfefe1461034a5780636d14a987146103755780637c172347146103b457806381c07502146103ce57600080fd5b80634bd26e09146102e55780635401ed27146103155780635e5a6775146103285780635f1f2d771461033757600080fd5b806320b66298116101c357806320b662981461026c57806325504777146102815780632cd95940146102a25780633ca5a5f5146102c257600080fd5b80630491b41c146101ea57806308732461146102205780631f9b74e014610241575b600080fd5b61020d6101f8366004612c27565b60ff1660009081526001602052604090205490565b6040519081526020015b60405180910390f35b61023361022e366004612c42565b610597565b604051610217929190612c6c565b61025461024f366004612ca6565b6105e0565b6040516001600160601b039091168152602001610217565b61027f61027a366004612d21565b610630565b005b61029461028f366004612de2565b610961565b604051610217929190612e81565b6102b56102b0366004612ea6565b610c2c565b6040516102179190612ed2565b61020d6102d0366004612c27565b60ff1660009081526003602052604090205490565b61020d6102f3366004612ea6565b600091825260026020908152604080842060ff93909316845291905290205490565b610254610323366004612ea6565b610ccb565b61020d670de0b6b3a764000081565b61027f610345366004612fdb565b610ce4565b61035d610358366004612de2565b611104565b6040516001600160c01b039091168152602001610217565b61039c7f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc981565b6040516001600160a01b039091168152602001610217565b6103bc602081565b60405160ff9091168152602001610217565b6103e16103dc366004613097565b61125e565b60405161021791906130e9565b61039c6103fc366004612c42565b611528565b61041461040f366004613127565b611560565b604051610217919061315a565b61043461042f366004612c42565b6115f8565b6040805182516001600160a01b031681526020928301516001600160601b03169281019290925201610217565b61041461046f366004612c42565b611672565b61027f6104823660046131a6565b611701565b61027f6104953660046131d0565b6117fa565b6102546104a8366004612c27565b6000602081905290815260409020546001600160601b031681565b61027f6104d136600461329c565b611927565b6102546104e43660046132e9565b611a1b565b6102546104f7366004612c27565b611a99565b61050f61050a366004613325565b611aec565b60405163ffffffff9091168152602001610217565b61039c7f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc981565b610254610559366004613361565b611b01565b61041461056c366004612ea6565b611b96565b61025461057f366004613325565b611c7b565b61027f6105923660046133a3565b611cdc565b600360205281600052604060002081815481106105b357600080fd5b6000918252602090912001546001600160a01b0381169250600160a01b90046001600160601b0316905082565b60ff8216600090815260016020526040812054839061061a5760405162461bcd60e51b815260040161061190613400565b60405180910390fd5b60006106268585611e47565b5095945050505050565b7f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc96001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561068e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b29190613451565b6001600160a01b0316336001600160a01b0316146106e25760405162461bcd60e51b81526004016106119061346e565b846106fe8160ff16600090815260016020526040902054151590565b61071a5760405162461bcd60e51b815260040161061190613400565b8380610790576040805162461bcd60e51b81526020600482015260248101919091527f5374616b6552656769737472792e6d6f6469667953747261746567795061726160448201527f6d733a206e6f20737472617465677920696e64696365732070726f76696465646064820152608401610611565b8281146108055760405162461bcd60e51b815260206004820152603960248201527f5374616b6552656769737472792e6d6f6469667953747261746567795061726160448201527f6d733a20696e707574206c656e677468206d69736d61746368000000000000006064820152608401610611565b60ff87166000908152600360205260408120905b8281101561095657858582818110610833576108336134ea565b90506020020160208101906108489190613500565b8289898481811061085b5761085b6134ea565b9050602002013581548110610872576108726134ea565b9060005260206000200160000160146101000a8154816001600160601b0302191690836001600160601b031602179055508860ff167f11a5641322da1dff56a4b66eaac31ffa465295ece907cd163437793b4d009a75838a8a858181106108db576108db6134ea565b90506020020135815481106108f2576108f26134ea565b6000918252602090912001546001600160a01b0316888885818110610919576109196134ea565b905060200201602081019061092e9190613500565b60405161093c929190612c6c565b60405180910390a28061094e81613531565b915050610819565b505050505050505050565b606080336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc916146109ac5760405162461bcd60e51b81526004016106119061354c565b6000836001600160401b038111156109c6576109c6612f4a565b6040519080825280602002602001820160405280156109ef578160200160208202803683370190505b5090506000846001600160401b03811115610a0c57610a0c612f4a565b604051908082528060200260200182016040528015610a35578160200160208202803683370190505b50905060005b85811015610c1e576000878783818110610a5757610a576134ea565b919091013560f81c60008181526001602052604090205490925015159050610adf5760405162461bcd60e51b815260206004820152603560248201527f5374616b6552656769737472792e72656769737465724f70657261746f723a206044820152741c5d5bdc9d5b48191bd95cc81b9bdd08195e1a5cdd605a1b6064820152608401610611565b600080610aec838d611e47565b9150915080610b895760405162461bcd60e51b815260206004820152605b60248201527f5374616b6552656769737472792e72656769737465724f70657261746f723a2060448201527f4f70657261746f7220646f6573206e6f74206d656574206d696e696d756d207360648201527f74616b6520726571756972656d656e7420666f722071756f72756d0000000000608482015260a401610611565b6000610b968c8585612045565b905082878681518110610bab57610bab6134ea565b60200260200101906001600160601b031690816001600160601b031681525050610bd584826122c5565b868681518110610be757610be76134ea565b60200260200101906001600160601b031690816001600160601b031681525050505050508080610c1690613531565b915050610a3b565b509097909650945050505050565b600082815260026020908152604080832060ff851684528252808320805482518185028101850190935280835260609492939192909184015b82821015610cbe576000848152602090819020604080516060810182529185015463ffffffff8082168452600160201b82041683850152600160401b90046001600160601b031690820152825260019092019101610c65565b5050505090505b92915050565b600080610cd88484611b96565b60400151949350505050565b7f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc96001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d669190613451565b6001600160a01b0316336001600160a01b031614610d965760405162461bcd60e51b81526004016106119061346e565b81610db28160ff16600090815260016020526040902054151590565b610dce5760405162461bcd60e51b815260040161061190613400565b815180610e435760405162461bcd60e51b815260206004820152603d60248201527f5374616b6552656769737472792e72656d6f7665537472617465676965733a2060448201527f6e6f20696e646963657320746f2072656d6f76652070726f76696465640000006064820152608401610611565b60ff841660009081526003602090815260408083206004909252822090915b838110156110fb578660ff167f31fa2e2cd280c9375e13ffcf3d81e2378100186e4058f8d3ddb690b82dcd31f784888481518110610ea257610ea26134ea565b602002602001015181548110610eba57610eba6134ea565b600091825260209182902001546040516001600160a01b0390911681520160405180910390a28660ff167f11a5641322da1dff56a4b66eaac31ffa465295ece907cd163437793b4d009a7584888481518110610f1857610f186134ea565b602002602001015181548110610f3057610f306134ea565b600091825260208083209190910154604080516001600160a01b039092168252918101929092520160405180910390a282548390610f70906001906135be565b81548110610f8057610f806134ea565b9060005260206000200183878381518110610f9d57610f9d6134ea565b602002602001015181548110610fb557610fb56134ea565b600091825260209091208254910180546001600160a01b0319166001600160a01b03909216918217815591546001600160601b03600160a01b9182900416021790558254839080611008576110086135d5565b60008281526020812082016000199081019190915501905581548290611030906001906135be565b81548110611040576110406134ea565b9060005260206000200160009054906101000a90046001600160a01b031682878381518110611071576110716134ea565b602002602001015181548110611089576110896134ea565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550818054806110c7576110c76135d5565b600082815260209020810160001990810180546001600160a01b0319169055019055806110f381613531565b915050610e62565b50505050505050565b6000336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc9161461114e5760405162461bcd60e51b81526004016106119061354c565b6000805b8381101561062657600085858381811061116e5761116e6134ea565b919091013560f81c600081815260016020526040902054909250151590506111fe5760405162461bcd60e51b815260206004820152603860248201527f5374616b6552656769737472792e7570646174654f70657261746f725374616b60448201527f653a2071756f72756d20646f6573206e6f7420657869737400000000000000006064820152608401610611565b60008061120b838b611e47565b915091508061122d5760009150600160ff84161b6001600160c01b0386161794505b600061123a8a8585612045565b905061124684826122c5565b5050505050808061125690613531565b915050611152565b60606000826001600160401b0381111561127a5761127a612f4a565b6040519080825280602002602001820160405280156112a3578160200160208202803683370190505b50905060005b8381101561151d5760008585838181106112c5576112c56134ea565b919091013560f81c600081815260016020526040902054909250151590506113645760405162461bcd60e51b815260206004820152604660248201527f5374616b6552656769737472792e676574546f74616c5374616b65496e64696360448201527f65734174426c6f636b4e756d6265723a2071756f72756d20646f6573206e6f7460648201526508195e1a5cdd60d21b608482015260a401610611565b60ff81166000908152600160205260408120805463ffffffff8a16929061138d5761138d6134ea565b60009182526020909120015463ffffffff1611156114395760405162461bcd60e51b815260206004820152605b60248201527f5374616b6552656769737472792e676574546f74616c5374616b65496e64696360448201527f65734174426c6f636b4e756d6265723a2071756f72756d20686173206e6f207360648201527f74616b6520686973746f727920617420626c6f636b4e756d6265720000000000608482015260a401610611565b60ff8116600090815260016020526040812054905b818110156115075760ff8316600090815260016020819052604090912063ffffffff8b169161147d84866135be565b61148791906135be565b81548110611497576114976134ea565b60009182526020909120015463ffffffff16116114f55760016114ba82846135be565b6114c491906135be565b8585815181106114d6576114d66134ea565b602002602001019063ffffffff16908163ffffffff1681525050611507565b806114ff81613531565b91505061144e565b505050808061151590613531565b9150506112a9565b5090505b9392505050565b6004602052816000526040600020818154811061154457600080fd5b6000918252602090912001546001600160a01b03169150829050565b60408051606081018252600080825260208083018290528284018290528582526002815283822060ff881683529052919091208054839081106115a5576115a56134ea565b600091825260209182902060408051606081018252929091015463ffffffff8082168452600160201b82041693830193909352600160401b9092046001600160601b031691810191909152949350505050565b604080518082019091526000808252602082015260ff83166000908152600360205260409020805483908110611630576116306134ea565b6000918252602091829020604080518082019091529101546001600160a01b0381168252600160a01b90046001600160601b0316918101919091529392505050565b604080516060810182526000808252602080830182905282840182905260ff8616825260019052919091208054839081106116af576116af6134ea565b600091825260209182902060408051606081018252929091015463ffffffff8082168452600160201b82041693830193909352600160401b9092046001600160601b0316918101919091529392505050565b7f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc96001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561175f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117839190613451565b6001600160a01b0316336001600160a01b0316146117b35760405162461bcd60e51b81526004016106119061346e565b816117cf8160ff16600090815260016020526040902054151590565b6117eb5760405162461bcd60e51b815260040161061190613400565b6117f5838361243f565b505050565b336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc916146118425760405162461bcd60e51b81526004016106119061354c565b60005b81811015611921576000838383818110611861576118616134ea565b919091013560f81c600081815260016020526040902054909250151590506118f15760405162461bcd60e51b815260206004820152603760248201527f5374616b6552656769737472792e646572656769737465724f70657261746f7260448201527f3a2071756f72756d20646f6573206e6f742065786973740000000000000000006064820152608401610611565b60006118ff86836000612045565b905061190b82826122c5565b505050808061191990613531565b915050611845565b50505050565b7f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc96001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611985573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a99190613451565b6001600160a01b0316336001600160a01b0316146119d95760405162461bcd60e51b81526004016106119061346e565b816119f58160ff16600090815260016020526040902054151590565b611a115760405162461bcd60e51b815260040161061190613400565b6117f583836124a8565b60ff83166000908152600160205260408120805482919084908110611a4257611a426134ea565b600091825260209182902060408051606081018252919092015463ffffffff8082168352600160201b820416938201939093526001600160601b03600160401b90930492909216908201529050610cd881856128eb565b60ff81166000908152600160208190526040822080549091611aba916135be565b81548110611aca57611aca6134ea565b600091825260209091200154600160401b90046001600160601b031692915050565b6000611af9848484612a65565b949350505050565b600082815260026020908152604080832060ff881684529091528120805482919084908110611b3257611b326134ea565b600091825260209182902060408051606081018252919092015463ffffffff8082168352600160201b820416938201939093526001600160601b03600160401b90930492909216908201529050611b8981866128eb565b6040015195945050505050565b6040805160608082018352600080835260208084018290528385018290528682526002815284822060ff87168352815284822054855193840186528284529083018290529382015290919081611bef579150610cc59050565b600085815260026020908152604080832060ff881684529091529020611c166001846135be565b81548110611c2657611c266134ea565b600091825260209182902060408051606081018252919092015463ffffffff8082168352600160201b820416938201939093526001600160601b03600160401b90930492909216908201529250610cc5915050565b600083815260026020908152604080832060ff861684529091528120611ca2858585612a65565b63ffffffff1681548110611cb857611cb86134ea565b600091825260209091200154600160401b90046001600160601b0316949350505050565b336001600160a01b037f000000000000000000000000a82ff9afd8f496c3d6ac40e2a0f282e47488cfc91614611d245760405162461bcd60e51b81526004016106119061354c565b60ff831660009081526001602052604090205415611da25760405162461bcd60e51b815260206004820152603560248201527f5374616b6552656769737472792e696e697469616c697a6551756f72756d3a2060448201527471756f72756d20616c72656164792065786973747360581b6064820152608401610611565b611dac83826124a8565b611db6838361243f565b505060ff166000908152600160208181526040808420815160608101835263ffffffff438116825281850187815293820187815283549687018455928752939095209451949093018054915193516001600160601b0316600160401b02600160401b600160a01b0319948416600160201b0267ffffffffffffffff1990931695909316949094171791909116179055565b600080600080611e668660ff1660009081526003602052604090205490565b604080518082019091526000808252602082015290915060ff871660009081526004602081905260408083209051639004134760e01b81526001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc91692639004134792611edb928c92016135eb565b600060405180830381865afa158015611ef8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f20919081019061364a565b905060005b838110156120115760ff89166000908152600360205260409020805482908110611f5157611f516134ea565b60009182526020808320604080518082019091529201546001600160a01b0381168352600160a01b90046001600160601b0316908201528351909450839083908110611f9f57611f9f6134ea565b60200260200101511115611fff57670de0b6b3a764000083602001516001600160601b0316838381518110611fd657611fd66134ea565b6020026020010151611fe891906136da565b611ff291906136f9565b611ffc908661371b565b94505b8061200981613531565b915050611f25565b50505060ff8616600090815260208190526040902054919350506001600160601b03908116908316101590505b9250929050565b600083815260026020908152604080832060ff8616845290915281205481908061210957600086815260026020908152604080832060ff891684528252808320815160608101835263ffffffff43811682528185018681526001600160601b03808c16958401958652845460018101865594885295909620915191909201805495519351909416600160401b02600160401b600160a01b0319938316600160201b0267ffffffffffffffff199096169190921617939093171691909117905561226b565b600086815260026020908152604080832060ff8916845290915281206121306001846135be565b81548110612140576121406134ea565b600091825260209091200180546001600160601b03600160401b9091048116945090915085168314156121795760009350505050611521565b80544363ffffffff908116911614156121b3578054600160401b600160a01b031916600160401b6001600160601b03871602178155612269565b805467ffffffff000000001916600160201b4363ffffffff90811682810293909317845560008a815260026020908152604080832060ff8d168452825280832081516060810183529687528683018481526001600160601b038d81169389019384528254600181018455928652939094209651960180549351915196851667ffffffffffffffff1990941693909317931690930291909117600160401b600160a01b031916600160401b93909216929092021790555b505b6040805160ff871681526001600160601b038616602082015287917f2f527d527e95d8fe40aec55377743bb779087da3f6d0d08f12e36444da62327d910160405180910390a26122bb8285612bcb565b9695505050505050565b60ff8216600090815260016020819052604082208054918391906122e990846135be565b815481106122f9576122f96134ea565b90600052602060002001905083600014156123285754600160401b90046001600160601b03169150610cc59050565b805460009061234790600160401b90046001600160601b031686612be3565b82549091504363ffffffff90811691161415612384578154600160401b600160a01b031916600160401b6001600160601b03831602178255612436565b815463ffffffff438116600160201b81810267ffffffff000000001990941693909317855560ff8916600090815260016020818152604080842081516060810183529586528583018581526001600160601b03808b169388019384528254958601835591865292909420945194909201805491519251909316600160401b02600160401b600160a01b031992861690960267ffffffffffffffff19909116939094169290921792909217169190911790555b95945050505050565b60ff82166000818152602081815260409182902080546bffffffffffffffffffffffff19166001600160601b03861690811790915591519182527f26eecff2b70b0a71104ff4d940ba7162d23a95c248771fc487a7be17a596b3cf910160405180910390a25050565b600081511161250d5760405162461bcd60e51b815260206004820152603860248201526000805160206137fa83398151915260448201527f3a206e6f20737472617465676965732070726f766964656400000000000000006064820152608401610611565b805160ff8316600090815260036020908152604090912054906125308383613746565b11156125a05760405162461bcd60e51b815260206004820152604560248201526000805160206137fa83398151915260448201527f3a20657863656564204d41585f5745494748494e475f46554e4354494f4e5f4c60648201526408a9c8ea8960db1b608482015260a401610611565b60005b828110156128e45760005b6125b88284613746565b811015612699578482815181106125d1576125d16134ea565b6020026020010151600001516001600160a01b0316600360008860ff1660ff1681526020019081526020016000208281548110612610576126106134ea565b6000918252602090912001546001600160a01b031614156126875760405162461bcd60e51b815260206004820152603d60248201526000805160206137fa83398151915260448201527f3a2063616e6e6f74206164642073616d652073747261746567792032780000006064820152608401610611565b8061269181613531565b9150506125ae565b5060008482815181106126ae576126ae6134ea565b6020026020010151602001516001600160601b0316116127335760405162461bcd60e51b815260206004820152604660248201526000805160206137fa83398151915260448201527f3a2063616e6e6f74206164642073747261746567792077697468207a65726f206064820152651dd95a59da1d60d21b608482015260a401610611565b60ff851660009081526003602052604090208451859083908110612759576127596134ea565b602090810291909101810151825460018101845560009384528284208251928401516001600160601b0316600160a01b026001600160a01b039093169290921791015560ff87168252600490526040902084518590839081106127be576127be6134ea565b6020908102919091018101515182546001810184556000938452919092200180546001600160a01b0319166001600160a01b03909216919091179055835160ff8616907f10565e56cacbf32eca267945f054fec02e59750032d113d3302182ad967f540490869084908110612835576128356134ea565b602090810291909101810151516040516001600160a01b0390911681520160405180910390a28460ff167f11a5641322da1dff56a4b66eaac31ffa465295ece907cd163437793b4d009a75858381518110612892576128926134ea565b6020026020010151600001518684815181106128b0576128b06134ea565b6020026020010151602001516040516128ca929190612c6c565b60405180910390a2806128dc81613531565b9150506125a3565b5050505050565b816000015163ffffffff168163ffffffff1610156129905760405162461bcd60e51b815260206004820152605660248201527f5374616b6552656769737472792e5f76616c69646174655374616b655570646160448201527f74654174426c6f636b4e756d6265723a207374616b6555706461746520697320606482015275333937b69030b33a32b910313637b1b5a73ab6b132b960511b608482015260a401610611565b602082015163ffffffff1615806129b65750816020015163ffffffff168163ffffffff16105b612a615760405162461bcd60e51b815260206004820152606a60248201527f5374616b6552656769737472792e5f76616c69646174655374616b655570646160448201527f74654174426c6f636b4e756d6265723a2074686572652069732061206e65776560648201527f72207374616b6555706461746520617661696c61626c65206265666f726520626084820152693637b1b5a73ab6b132b960b11b60a482015260c401610611565b5050565b600083815260026020908152604080832060ff86168452909152812054805b8015612b0657600086815260026020908152604080832060ff89168452909152902063ffffffff851690612ab96001846135be565b81548110612ac957612ac96134ea565b60009182526020909120015463ffffffff1611612af457612aeb6001826135be565b92505050611521565b80612afe8161375e565b915050612a84565b5060405162461bcd60e51b815260206004820152608160248201527f5374616b6552656769737472792e5f6765745374616b65557064617465496e6460448201527f6578466f724f70657261746f724174426c6f636b4e756d6265723a206e6f207360648201527f74616b652075706461746520666f756e6420666f72206f70657261746f72496460848201527f20616e642071756f72756d4e756d62657220617420626c6f636b206e756d626560a4820152603960f91b60c482015260e401610611565b60006115216001600160601b03808516908416613775565b600080821215612c0757612bf6826137b4565b612c0090846137d1565b9050610cc5565b612c00828461371b565b803560ff81168114612c2257600080fd5b919050565b600060208284031215612c3957600080fd5b61152182612c11565b60008060408385031215612c5557600080fd5b612c5e83612c11565b946020939093013593505050565b6001600160a01b039290921682526001600160601b0316602082015260400190565b6001600160a01b0381168114612ca357600080fd5b50565b60008060408385031215612cb957600080fd5b612cc283612c11565b91506020830135612cd281612c8e565b809150509250929050565b60008083601f840112612cef57600080fd5b5081356001600160401b03811115612d0657600080fd5b6020830191508360208260051b850101111561203e57600080fd5b600080600080600060608688031215612d3957600080fd5b612d4286612c11565b945060208601356001600160401b0380821115612d5e57600080fd5b612d6a89838a01612cdd565b90965094506040880135915080821115612d8357600080fd5b50612d9088828901612cdd565b969995985093965092949392505050565b60008083601f840112612db357600080fd5b5081356001600160401b03811115612dca57600080fd5b60208301915083602082850101111561203e57600080fd5b60008060008060608587031215612df857600080fd5b8435612e0381612c8e565b93506020850135925060408501356001600160401b03811115612e2557600080fd5b612e3187828801612da1565b95989497509550505050565b600081518084526020808501945080840160005b83811015612e765781516001600160601b031687529582019590820190600101612e51565b509495945050505050565b604081526000612e946040830185612e3d565b82810360208401526124368185612e3d565b60008060408385031215612eb957600080fd5b82359150612ec960208401612c11565b90509250929050565b6020808252825182820181905260009190848201906040850190845b81811015612f3e57612f2b83855163ffffffff808251168352806020830151166020840152506001600160601b0360408201511660408301525050565b9284019260609290920191600101612eee565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715612f8257612f82612f4a565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612fb057612fb0612f4a565b604052919050565b60006001600160401b03821115612fd157612fd1612f4a565b5060051b60200190565b60008060408385031215612fee57600080fd5b612ff783612c11565b91506020808401356001600160401b0381111561301357600080fd5b8401601f8101861361302457600080fd5b803561303761303282612fb8565b612f88565b81815260059190911b8201830190838101908883111561305657600080fd5b928401925b828410156130745783358252928401929084019061305b565b80955050505050509250929050565b803563ffffffff81168114612c2257600080fd5b6000806000604084860312156130ac57600080fd5b6130b584613083565b925060208401356001600160401b038111156130d057600080fd5b6130dc86828701612da1565b9497909650939450505050565b6020808252825182820181905260009190848201906040850190845b81811015612f3e57835163ffffffff1683529284019291840191600101613105565b60008060006060848603121561313c57600080fd5b61314584612c11565b95602085013595506040909401359392505050565b815163ffffffff9081168252602080840151909116908201526040808301516001600160601b03169082015260608101610cc5565b80356001600160601b0381168114612c2257600080fd5b600080604083850312156131b957600080fd5b6131c283612c11565b9150612ec96020840161318f565b6000806000604084860312156131e557600080fd5b8335925060208401356001600160401b038111156130d057600080fd5b600082601f83011261321357600080fd5b8135602061322361303283612fb8565b82815260069290921b8401810191818101908684111561324257600080fd5b8286015b84811015613291576040818903121561325f5760008081fd5b613267612f60565b813561327281612c8e565b815261327f82860161318f565b81860152835291830191604001613246565b509695505050505050565b600080604083850312156132af57600080fd5b6132b883612c11565b915060208301356001600160401b038111156132d357600080fd5b6132df85828601613202565b9150509250929050565b6000806000606084860312156132fe57600080fd5b61330784612c11565b925061331560208501613083565b9150604084013590509250925092565b60008060006060848603121561333a57600080fd5b8335925061334a60208501612c11565b915061335860408501613083565b90509250925092565b6000806000806080858703121561337757600080fd5b61338085612c11565b935061338e60208601613083565b93969395505050506040820135916060013590565b6000806000606084860312156133b857600080fd5b6133c184612c11565b92506133cf6020850161318f565b915060408401356001600160401b038111156133ea57600080fd5b6133f686828701613202565b9150509250925092565b60208082526031908201527f5374616b6552656769737472792e71756f72756d4578697374733a2071756f726040820152701d5b48191bd95cc81b9bdd08195e1a5cdd607a1b606082015260800190565b60006020828403121561346357600080fd5b815161152181612c8e565b60208082526056908201527f5374616b6552656769737472792e6f6e6c79436f6f7264696e61746f724f776e60408201527f65723a2063616c6c6572206973206e6f7420746865206f776e6572206f6620746060820152753432903932b3b4b9ba393ca1b7b7b93234b730ba37b960511b608082015260a00190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561351257600080fd5b6115218261318f565b634e487b7160e01b600052601160045260246000fd5b60006000198214156135455761354561351b565b5060010190565b6020808252604c908201527f5374616b6552656769737472792e6f6e6c795265676973747279436f6f72646960408201527f6e61746f723a2063616c6c6572206973206e6f7420746865205265676973747260608201526b3ca1b7b7b93234b730ba37b960a11b608082015260a00190565b6000828210156135d0576135d061351b565b500390565b634e487b7160e01b600052603160045260246000fd5b60006040820160018060a01b03808616845260206040818601528286548085526060870191508760005282600020945060005b8181101561363c57855485168352600195860195928401920161361e565b509098975050505050505050565b6000602080838503121561365d57600080fd5b82516001600160401b0381111561367357600080fd5b8301601f8101851361368457600080fd5b805161369261303282612fb8565b81815260059190911b820183019083810190878311156136b157600080fd5b928401925b828410156136cf578351825292840192908401906136b6565b979650505050505050565b60008160001904831182151516156136f4576136f461351b565b500290565b60008261371657634e487b7160e01b600052601260045260246000fd5b500490565b60006001600160601b0380831681851680830382111561373d5761373d61351b565b01949350505050565b600082198211156137595761375961351b565b500190565b60008161376d5761376d61351b565b506000190190565b60008083128015600160ff1b8501841216156137935761379361351b565b6001600160ff1b03840183138116156137ae576137ae61351b565b50500390565b6000600160ff1b8214156137ca576137ca61351b565b5060000390565b60006001600160601b03838116908316818110156137f1576137f161351b565b03939250505056fe5374616b6552656769737472792e5f6164645374726174656779506172616d73a264697066735822122006dbbe593b2e029b43e20bae20240fb16d756141cdff832b90b124e4d6c514b264736f6c634300080c0033","storage":{}},"0x9a676e781a523b5d0c0e43731313a708cb607508":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106101f05760003560e01c80637cf72bba1161010f578063d98128c0116100a2578063e921d4fa11610071578063e921d4fa146103c6578063f2fde38b1461044c578063f73b7519146102a9578063fabc1cbc1461045f57600080fd5b8063d98128c014610430578063da16e29b14610322578063df5cf723146102ba578063e58398361461043e57600080fd5b80638da5cb5b116100de5780638da5cb5b146103b5578063a49db732146103c6578063c747075b146103da578063d7b7fa13146103ee57600080fd5b80637cf72bba146103465780638105e04314610354578063855fcc4a1461036b578063886f1195146103a257600080fd5b806339b70e38116101875780636f0c2f74116101565780636f0c2f7414610322578063715018a614610330578063723e59c7146103385780637259a45c1461024257600080fd5b806339b70e38146102ba578063595c6a67146102d55780635ac86ab7146102dd5780635c975abb1461031057600080fd5b80631794bb3c116101c35780631794bb3c1461022f5780631874e5ae14610242578063282670fc1461027257806338c8ee64146102a957600080fd5b80630ffabbce146101f557806310d67a2f14610209578063136439dd1461021c578063175d3205146101f5575b600080fd5b610207610203366004610b25565b5050565b005b610207610217366004610b5a565b610472565b61020761022a366004610b7e565b61052b565b61020761023d366004610b97565b505050565b610258610250366004610b25565b600092915050565b60405163ffffffff90911681526020015b60405180910390f35b610285610280366004610bd8565b61066a565b60408051825163ffffffff9081168252602093840151169281019290925201610269565b6102076102b7366004610b5a565b50565b60005b6040516001600160a01b039091168152602001610269565b610207610685565b6103006102eb366004610c04565b606654600160ff9092169190911b9081161490565b6040519015158152602001610269565b6066545b604051908152602001610269565b610258610250366004610c27565b61020761074c565b610314610250366004610b25565b610207610203366004610c60565b610300610362366004610cd5565b60009392505050565b610385610379366004610c27565b60008060009250925092565b604080519315158452602084019290925290820152606001610269565b6065546102bd906001600160a01b031681565b6033546001600160a01b03166102bd565b6103146103d4366004610b5a565b50600090565b6102076103e8366004610d13565b50505050565b6104016103fc366004610c27565b610760565b60408051825163ffffffff90811682526020808501518216908301529282015190921690820152606001610269565b610300610250366004610c27565b6103006103d4366004610b5a565b61020761045a366004610b5a565b610782565b61020761046d366004610b7e565b6107f8565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e99190610d60565b6001600160a01b0316336001600160a01b0316146105225760405162461bcd60e51b815260040161051990610d7d565b60405180910390fd5b6102b781610954565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610573573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105979190610dc7565b6105b35760405162461bcd60e51b815260040161051990610de9565b6066548181161461062c5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610519565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b60408051808201909152600080825260208201525b92915050565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156106cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f19190610dc7565b61070d5760405162461bcd60e51b815260040161051990610de9565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b610754610a4b565b61075e6000610aa5565b565b604080516060810182526000808252602082018190529181019190915261067f565b61078a610a4b565b6001600160a01b0381166107ef5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610519565b6102b781610aa5565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561084b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086f9190610d60565b6001600160a01b0316336001600160a01b03161461089f5760405162461bcd60e51b815260040161051990610d7d565b60665419811960665419161461091d5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610519565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c9060200161065f565b6001600160a01b0381166109e25760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610519565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b0316331461075e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610519565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03811681146102b757600080fd5b803563ffffffff81168114610b2057600080fd5b919050565b60008060408385031215610b3857600080fd5b8235610b4381610af7565b9150610b5160208401610b0c565b90509250929050565b600060208284031215610b6c57600080fd5b8135610b7781610af7565b9392505050565b600060208284031215610b9057600080fd5b5035919050565b600080600060608486031215610bac57600080fd5b8335610bb781610af7565b92506020840135610bc781610af7565b929592945050506040919091013590565b60008060408385031215610beb57600080fd5b8235610bf681610af7565b946020939093013593505050565b600060208284031215610c1657600080fd5b813560ff81168114610b7757600080fd5b60008060408385031215610c3a57600080fd5b8235610c4581610af7565b91506020830135610c5581610af7565b809150509250929050565b60008060208385031215610c7357600080fd5b823567ffffffffffffffff80821115610c8b57600080fd5b818501915085601f830112610c9f57600080fd5b813581811115610cae57600080fd5b8660208260051b8501011115610cc357600080fd5b60209290920196919550909350505050565b600080600060608486031215610cea57600080fd5b8335610cf581610af7565b9250610d0360208501610b0c565b9150604084013590509250925092565b60008060008060808587031215610d2957600080fd5b8435610d3481610af7565b9350610d4260208601610b0c565b9250610d5060408601610b0c565b9396929550929360600135925050565b600060208284031215610d7257600080fd5b8151610b7781610af7565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215610dd957600080fd5b81518015158114610b7757600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b60608201526080019056fea26469706673582212200fdcdd4bbe9965fc5e3814959bc3a46f4e2bf80b0e8c4971318887ad46a8d84564736f6c634300080c0033","storage":{}},"0x9d4454b023096f34b160d6b654540c56a1f81688":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106102945760003560e01c80635df45946116101675780639feab859116100ce578063d75b4c8811610087578063d75b4c88146106f5578063dd8283f314610708578063e65797ad1461071b578063f2fde38b146107be578063fabc1cbc146107d1578063fd39105a146107e457600080fd5b80639feab85914610659578063a50857bf14610680578063c391425e14610693578063ca0de882146106b3578063ca4f2d97146106da578063d72d8dd6146106ed57600080fd5b8063871ef04911610120578063871ef049146105cc578063886f1195146105df5780638da5cb5b146105f85780639aa1653d146106005780639b5d177b1461061f5780639e9923c21461063257600080fd5b80635df459461461053d5780636347c9001461056457806368304835146105775780636e3b17db1461059e578063715018a6146105b157806384ca5213146105b957600080fd5b806328f61b311161020b5780635140a548116101c45780635140a548146104c85780635865c60c146104db578063595c6a67146104fb5780635ac86ab7146105035780635b0b829f146105225780635c975abb1461053557600080fd5b806328f61b3114610435578063296bb0641461044857806329d1e0c31461045b5780632cdd1e861461046e5780633998fdd3146104815780633c2a7f4c146104a857600080fd5b806310d67a2f1161025d57806310d67a2f1461034a57806313542a4e1461035d578063136439dd146103865780631478851f146103995780631eb812da146103cc578063249a0c421461041557600080fd5b8062cf2ab51461029957806303fd3492146102ae57806304ec6351146102e1578063054310e61461030c5780630cf4b76714610337575b600080fd5b6102ac6102a73660046148b5565b610820565b005b6102ce6102bc3660046148f6565b60009081526098602052604090205490565b6040519081526020015b60405180910390f35b6102f46102ef366004614921565b610936565b6040516001600160c01b0390911681526020016102d8565b609d5461031f906001600160a01b031681565b6040516001600160a01b0390911681526020016102d8565b6102ac610345366004614a40565b610b2c565b6102ac610358366004614ab5565b610c14565b6102ce61036b366004614ab5565b6001600160a01b031660009081526099602052604090205490565b6102ac6103943660046148f6565b610cc7565b6103bc6103a73660046148f6565b609a6020526000908152604090205460ff1681565b60405190151581526020016102d8565b6103df6103da366004614ad2565b610e04565b60408051825163ffffffff908116825260208085015190911690820152918101516001600160c01b0316908201526060016102d8565b6102ce610423366004614b05565b609b6020526000908152604090205481565b609e5461031f906001600160a01b031681565b61031f6104563660046148f6565b610e95565b6102ac610469366004614ab5565b610f21565b6102ac61047c366004614ab5565b610f32565b61031f7f00000000000000000000000084ea74d481ee0a5332c457a4d796187f6ba67feb81565b6104bb6104b6366004614ab5565b610f43565b6040516102d89190614b20565b6102ac6104d6366004614b78565b610fc2565b6104ee6104e9366004614ab5565b6114d3565b6040516102d89190614c1b565b6102ac611547565b6103bc610511366004614b05565b6001805460ff9092161b9081161490565b6102ac610530366004614ca0565b611613565b6001546102ce565b61031f7f0000000000000000000000001613beb3b2c4f22ee086b2b38c1476a3ce7f78e881565b61031f6105723660046148f6565b6116aa565b61031f7f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f3681565b6102ac6105ac366004614cd4565b6116d4565b6102ac611794565b6102ce6105c7366004614d8b565b6117a8565b6102f46105da3660046148f6565b6117f2565b60005461031f906201000090046001600160a01b031681565b61031f6117fd565b60965461060d9060ff1681565b60405160ff90911681526020016102d8565b6102ac61062d366004614f24565b611816565b61031f7f000000000000000000000000851356ae760d987e095750cceb3bc6014560891c81565b6102ce7f2bd82124057f0913bc3b772ce7b83e8057c1ad1f3510fc83778be20f10ec5de681565b6102ac61068e36600461501d565b611b4e565b6106a66106a13660046150c5565b611cd2565b6040516102d8919061516a565b6102ce7f4d404e3276e7ac2163d8ee476afa6a41d1f68fb71f2d8b6546b24e55ce01b72a81565b6102ac6106e83660046151b4565b611d8b565b609c546102ce565b6102ac61070336600461529a565b611df2565b6102ac61071636600461544d565b611e05565b61078a610729366004614b05565b60408051606080820183526000808352602080840182905292840181905260ff9490941684526097825292829020825193840183525463ffffffff8116845261ffff600160201b8204811692850192909252600160301b9004169082015290565b60408051825163ffffffff16815260208084015161ffff9081169183019190915292820151909216908201526060016102d8565b6102ac6107cc366004614ab5565b612109565b6102ac6107df3660046148f6565b61217f565b6108136107f2366004614ab5565b6001600160a01b031660009081526099602052604090206001015460ff1690565b6040516102d89190615521565b600154600290600490811614156108525760405162461bcd60e51b81526004016108499061552f565b60405180910390fd5b60005b8281101561093057600084848381811061087157610871615566565b90506020020160208101906108869190614ab5565b6001600160a01b03811660009081526099602090815260408083208151808301909252805482526001810154949550929390929183019060ff1660028111156108d1576108d1614be3565b60028111156108e2576108e2614be3565b905250805190915060006108f5826122db565b9050600061090b826001600160c01b0316612344565b9050610918858583612410565b5050505050808061092890615592565b915050610855565b50505050565b600083815260986020526040812080548291908490811061095957610959615566565b600091825260209182902060408051606081018252929091015463ffffffff808216808552600160201b8304821695850195909552600160401b9091046001600160c01b03169183019190915290925085161015610a535760405162461bcd60e51b815260206004820152606560248201527f5265676973747279436f6f7264696e61746f722e67657451756f72756d42697460448201527f6d61704174426c6f636b4e756d6265724279496e6465783a2071756f72756d4260648201527f69746d61705570646174652069732066726f6d20616674657220626c6f636b4e6084820152643ab6b132b960d91b60a482015260c401610849565b602081015163ffffffff161580610a795750806020015163ffffffff168463ffffffff16105b610b205760405162461bcd60e51b815260206004820152606660248201527f5265676973747279436f6f7264696e61746f722e67657451756f72756d42697460448201527f6d61704174426c6f636b4e756d6265724279496e6465783a2071756f72756d4260648201527f69746d61705570646174652069732066726f6d206265666f726520626c6f636b608482015265273ab6b132b960d11b60a482015260c401610849565b60400151949350505050565b60013360009081526099602052604090206001015460ff166002811115610b5557610b55614be3565b14610bc85760405162461bcd60e51b815260206004820152603c60248201527f5265676973747279436f6f7264696e61746f722e757064617465536f636b657460448201527f3a206f70657261746f72206973206e6f742072656769737465726564000000006064820152608401610849565b33600090815260996020526040908190205490517fec2963ab21c1e50e1e582aa542af2e4bf7bf38e6e1403c27b42e1c5d6e621eaa90610c099084906155fa565b60405180910390a250565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8b919061560d565b6001600160a01b0316336001600160a01b031614610cbb5760405162461bcd60e51b81526004016108499061562a565b610cc4816124fd565b50565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610d14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d389190615674565b610d545760405162461bcd60e51b815260040161084990615696565b60015481811614610dcd5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610849565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d90602001610c09565b60408051606081018252600080825260208201819052918101919091526000838152609860205260409020805483908110610e4157610e41615566565b600091825260209182902060408051606081018252919092015463ffffffff8082168352600160201b820416938201939093526001600160c01b03600160401b909304929092169082015290505b92915050565b6040516308f6629d60e31b8152600481018290526000907f0000000000000000000000001613beb3b2c4f22ee086b2b38c1476a3ce7f78e86001600160a01b0316906347b314e890602401602060405180830381865afa158015610efd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8f919061560d565b610f29612602565b610cc481612661565b610f3a612602565b610cc4816126ca565b6040805180820190915260008082526020820152610e8f610fbd7f2bd82124057f0913bc3b772ce7b83e8057c1ad1f3510fc83778be20f10ec5de684604051602001610fa29291909182526001600160a01b0316602082015260400190565b60405160208183030381529060405280519060200120612733565b612781565b60015460029060049081161415610feb5760405162461bcd60e51b81526004016108499061552f565b600061103384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060965460ff1691506128119050565b90508483146110a45760405162461bcd60e51b81526020600482015260436024820152600080516020615d2e83398151915260448201527f6f7273466f7251756f72756d3a20696e707574206c656e677468206d69736d616064820152620e8c6d60eb1b608482015260a401610849565b60005b838110156114ca5760008585838181106110c3576110c3615566565b919091013560f81c915036905060008989858181106110e4576110e4615566565b90506020028101906110f691906156de565b6040516379a0849160e11b815260ff8616600482015291935091507f000000000000000000000000851356ae760d987e095750cceb3bc6014560891c6001600160a01b03169063f341092290602401602060405180830381865afa158015611162573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111869190615727565b63ffffffff1681146112225760405162461bcd60e51b81526020600482015260656024820152600080516020615d2e83398151915260448201527f6f7273466f7251756f72756d3a206e756d626572206f6620757064617465642060648201527f6f70657261746f727320646f6573206e6f74206d617463682071756f72756d206084820152641d1bdd185b60da1b60a482015260c401610849565b6000805b8281101561146957600084848381811061124257611242615566565b90506020020160208101906112579190614ab5565b6001600160a01b03811660009081526099602090815260408083208151808301909252805482526001810154949550929390929183019060ff1660028111156112a2576112a2614be3565b60028111156112b3576112b3614be3565b905250805190915060006112c6826122db565b905060016001600160c01b03821660ff8b161c81161461134a5760405162461bcd60e51b815260206004820152604460248201819052600080516020615d2e833981519152908201527f6f7273466f7251756f72756d3a206f70657261746f72206e6f7420696e2071756064820152636f72756d60e01b608482015260a401610849565b856001600160a01b0316846001600160a01b0316116113f55760405162461bcd60e51b81526020600482015260676024820152600080516020615d2e83398151915260448201527f6f7273466f7251756f72756d3a206f70657261746f7273206172726179206d7560648201527f737420626520736f7274656420696e20617363656e64696e6720616464726573608482015266399037b93232b960c91b60a482015260c401610849565b5061145383838f8f8d908e600161140c9190615744565b926114199392919061575c565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061241092505050565b50909250611462905081615592565b9050611226565b5060ff84166000818152609b6020908152604091829020439081905591519182527f46077d55330763f16269fd75e5761663f4192d2791747c0189b16ad31db07db4910160405180910390a250505050806114c390615592565b90506110a7565b50505050505050565b60408051808201909152600080825260208201526001600160a01b0382166000908152609960209081526040918290208251808401909352805483526001810154909183019060ff16600281111561152d5761152d614be3565b600281111561153e5761153e614be3565b90525092915050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015611594573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b89190615674565b6115d45760405162461bcd60e51b815260040161084990615696565b600019600181905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b61161b612602565b609654829060ff9081169082161061169b5760405162461bcd60e51b815260206004820152603760248201527f5265676973747279436f6f7264696e61746f722e71756f72756d45786973747360448201527f3a2071756f72756d20646f6573206e6f742065786973740000000000000000006064820152608401610849565b6116a583836128a2565b505050565b609c81815481106116ba57600080fd5b6000918252602090912001546001600160a01b0316905081565b609e546001600160a01b031633146117545760405162461bcd60e51b815260206004820152603a60248201527f5265676973747279436f6f7264696e61746f722e6f6e6c79456a6563746f723a60448201527f2063616c6c6572206973206e6f742074686520656a6563746f720000000000006064820152608401610849565b6116a58383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061294f92505050565b61179c612602565b6117a66000612dc1565b565b60006117e87f4d404e3276e7ac2163d8ee476afa6a41d1f68fb71f2d8b6546b24e55ce01b72a8787878787604051602001610fa296959493929190615786565b9695505050505050565b6000610e8f826122db565b60006118116064546001600160a01b031690565b905090565b60018054600091908116141561183e5760405162461bcd60e51b81526004016108499061552f565b8389146118c15760405162461bcd60e51b8152602060048201526044602482018190527f5265676973747279436f6f7264696e61746f722e72656769737465724f706572908201527f61746f7257697468436875726e3a20696e707574206c656e677468206d69736d6064820152630c2e8c6d60e31b608482015260a401610849565b60006118cd3388612e13565b905061192d33828888808060200260200160405190810160405280939291908181526020016000905b82821015611922576119136040830286013681900381019061580b565b815260200190600101906118f6565b505050505087612f44565b600061197433838e8e8e8e8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92506130d1915050565b905060005b8b811015611b3f576000609760008f8f8581811061199957611999615566565b919091013560f81c82525060208082019290925260409081016000208151606081018352905463ffffffff811680835261ffff600160201b8304811695840195909552600160301b90910490931691810191909152845180519193509084908110611a0657611a06615566565b602002602001015163ffffffff161115611b2c57611aa78e8e84818110611a2f57611a2f615566565b9050013560f81c60f81b60f81c84604001518481518110611a5257611a52615566565b60200260200101513386602001518681518110611a7157611a71615566565b60200260200101518d8d88818110611a8b57611a8b615566565b905060400201803603810190611aa1919061580b565b866135e8565b611b2c898984818110611abc57611abc615566565b9050604002016020016020810190611ad49190614ab5565b8f8f8590866001611ae59190615744565b92611af29392919061575c565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061294f92505050565b5080611b3781615592565b915050611979565b50505050505050505050505050565b600180546000919081161415611b765760405162461bcd60e51b81526004016108499061552f565b6000611b823385612e13565b90506000611bcb33838b8b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92506130d1915050565b51905060005b88811015611cc65760008a8a83818110611bed57611bed615566565b919091013560f81c600081815260976020526040902054855191935063ffffffff169150849084908110611c2357611c23615566565b602002602001015163ffffffff161115611cb35760405162461bcd60e51b8152602060048201526044602482018190527f5265676973747279436f6f7264696e61746f722e72656769737465724f706572908201527f61746f723a206f70657261746f7220636f756e742065786365656473206d6178606482015263696d756d60e01b608482015260a401610849565b5080611cbe81615592565b915050611bd1565b50505050505050505050565b6060600082516001600160401b03811115611cef57611cef614959565b604051908082528060200260200182016040528015611d18578160200160208202803683370190505b50905060005b8351811015611d8357611d4a85858381518110611d3d57611d3d615566565b60200260200101516138bd565b828281518110611d5c57611d5c615566565b63ffffffff9092166020928302919091019091015280611d7b81615592565b915050611d1e565b509392505050565b6001805460029081161415611db25760405162461bcd60e51b81526004016108499061552f565b6116a53384848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061294f92505050565b611dfa612602565b6116a58383836139f9565b600054610100900460ff1615808015611e255750600054600160ff909116105b80611e3f5750303b158015611e3f575060005460ff166001145b611ea25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610849565b6000805460ff191660011790558015611ec5576000805461ff0019166101001790555b82518451148015611ed7575081518351145b611f415760405162461bcd60e51b815260206004820152603560248201527f5265676973747279436f6f7264696e61746f722e696e697469616c697a653a206044820152740d2dce0eae840d8cadccee8d040dad2e6dac2e8c6d605b1b6064820152608401610849565b611f4a89612dc1565b611f548686613c10565b611f5d88612661565b611f66876126ca565b609c80546001818101835560008381527faf85b9071dfafeac1409d3f1d19bafc9bc7c37974cde8df0ee6168f0086e539c92830180546001600160a01b037f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f3681166001600160a01b03199283161790925585548085018755850180547f0000000000000000000000001613beb3b2c4f22ee086b2b38c1476a3ce7f78e8841690831617905585549384019095559190920180547f000000000000000000000000851356ae760d987e095750cceb3bc6014560891c90921691909316179091555b84518110156120b7576120a585828151811061206457612064615566565b602002602001015185838151811061207e5761207e615566565b602002602001015185848151811061209857612098615566565b60200260200101516139f9565b806120af81615592565b915050612046565b5080156120fe576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050505050565b612111612602565b6001600160a01b0381166121765760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610849565b610cc481612dc1565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f6919061560d565b6001600160a01b0316336001600160a01b0316146122265760405162461bcd60e51b81526004016108499061562a565b6001541981196001541916146122a45760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610849565b600181905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610c09565b600081815260986020526040812054806122f85750600092915050565b6000838152609860205260409020612311600183615827565b8154811061232157612321615566565b600091825260209091200154600160401b90046001600160c01b03169392505050565b606060008061235284613d00565b61ffff166001600160401b0381111561236d5761236d614959565b6040519080825280601f01601f191660200182016040528015612397576020820181803683370190505b5090506000805b8251821080156123af575061010081105b15612406576001811b9350858416156123f6578060f81b8383815181106123d8576123d8615566565b60200101906001600160f81b031916908160001a9053508160010191505b6123ff81615592565b905061239e565b5090949350505050565b60018260200151600281111561242857612428614be3565b1461243257505050565b81516040516333567f7f60e11b81526000906001600160a01b037f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f3616906366acfefe906124879088908690889060040161583e565b6020604051808303816000875af11580156124a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ca919061586e565b90506001600160c01b038116156124f6576124f6856124f1836001600160c01b0316612344565b61294f565b5050505050565b6001600160a01b03811661258b5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610849565b600054604080516001600160a01b03620100009093048316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b3361260b6117fd565b6001600160a01b0316146117a65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610849565b609d54604080516001600160a01b03928316815291831660208301527f315457d8a8fe60f04af17c16e2f5a5e1db612b31648e58030360759ef8f3528c910160405180910390a1609d80546001600160a01b0319166001600160a01b0392909216919091179055565b609e54604080516001600160a01b03928316815291831660208301527f8f30ab09f43a6c157d7fce7e0a13c003042c1c95e8a72e7a146a21c0caa24dc9910160405180910390a1609e80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610e8f612740613d2b565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b6040805180820190915260008082526020820152600080806127b1600080516020615d6e833981519152866158ad565b90505b6127bd81613e52565b9093509150600080516020615d6e8339815191528283098314156127f7576040805180820190915290815260208101919091529392505050565b600080516020615d6e8339815191526001820890506127b4565b60008061281d84613ed4565b9050808360ff166001901b1161289b5760405162461bcd60e51b815260206004820152603f60248201527f4269746d61705574696c732e6f72646572656442797465734172726179546f4260448201527f69746d61703a206269746d61702065786365656473206d61782076616c7565006064820152608401610849565b9392505050565b60ff8216600081815260976020908152604091829020845181548684018051888701805163ffffffff90951665ffffffffffff199094168417600160201b61ffff938416021767ffff0000000000001916600160301b95831695909502949094179094558551918252518316938101939093525116918101919091527f3ee6fe8d54610244c3e9d3c066ae4aee997884aa28f10616ae821925401318ac9060600160405180910390a25050565b6001600160a01b0382166000908152609960205260409020805460018083015460ff16600281111561298357612983614be3565b14612a025760405162461bcd60e51b815260206004820152604360248201527f5265676973747279436f6f7264696e61746f722e5f646572656769737465724f60448201527f70657261746f723a206f70657261746f72206973206e6f7420726567697374656064820152621c995960ea1b608482015260a401610849565b609654600090612a1690859060ff16612811565b90506000612a23836122db565b90506001600160c01b038216612aa15760405162461bcd60e51b815260206004820152603b60248201527f5265676973747279436f6f7264696e61746f722e5f646572656769737465724f60448201527f70657261746f723a206269746d61702063616e6e6f74206265203000000000006064820152608401610849565b612ab86001600160c01b0383811690831681161490565b612b505760405162461bcd60e51b815260206004820152605960248201527f5265676973747279436f6f7264696e61746f722e5f646572656769737465724f60448201527f70657261746f723a206f70657261746f72206973206e6f74207265676973746560648201527f72656420666f72207370656369666965642071756f72756d7300000000000000608482015260a401610849565b6001600160c01b0382811619821616612b698482614061565b6001600160c01b038116612c385760018501805460ff191660021790556040516351b27a6d60e11b81526001600160a01b0388811660048301527f00000000000000000000000084ea74d481ee0a5332c457a4d796187f6ba67feb169063a364f4da90602401600060405180830381600087803b158015612be957600080fd5b505af1158015612bfd573d6000803e3d6000fd5b50506040518692506001600160a01b038a1691507f396fdcb180cb0fea26928113fb0fd1c3549863f9cd563e6a184f1d578116c8e490600090a35b60405163f4e24fe560e01b81526001600160a01b037f0000000000000000000000001613beb3b2c4f22ee086b2b38c1476a3ce7f78e8169063f4e24fe590612c86908a908a906004016158c1565b600060405180830381600087803b158015612ca057600080fd5b505af1158015612cb4573d6000803e3d6000fd5b505060405163bd29b8cd60e01b81526001600160a01b037f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f3616925063bd29b8cd9150612d069087908a906004016158e5565b600060405180830381600087803b158015612d2057600080fd5b505af1158015612d34573d6000803e3d6000fd5b505060405163bd29b8cd60e01b81526001600160a01b037f000000000000000000000000851356ae760d987e095750cceb3bc6014560891c16925063bd29b8cd9150612d869087908a906004016158e5565b600060405180830381600087803b158015612da057600080fd5b505af1158015612db4573d6000803e3d6000fd5b5050505050505050505050565b606480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040516309aa152760e11b81526001600160a01b0383811660048301526000917f0000000000000000000000001613beb3b2c4f22ee086b2b38c1476a3ce7f78e8909116906313542a4e90602401602060405180830381865afa158015612e7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ea291906158fe565b905080610e8f577f0000000000000000000000001613beb3b2c4f22ee086b2b38c1476a3ce7f78e86001600160a01b031663bf79ce588484612ee387610f43565b6040518463ffffffff1660e01b8152600401612f0193929190615917565b6020604051808303816000875af1158015612f20573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061289b91906158fe565b6020808201516000908152609a909152604090205460ff1615612fea5760405162461bcd60e51b815260206004820152605260248201527f5265676973747279436f6f7264696e61746f722e5f766572696679436875726e60448201527f417070726f7665725369676e61747572653a20636875726e417070726f766572606482015271081cd85b1d08185b1c9958591e481d5cd95960721b608482015260a401610849565b428160400151101561307f5760405162461bcd60e51b815260206004820152605260248201527f5265676973747279436f6f7264696e61746f722e5f766572696679436875726e60448201527f417070726f7665725369676e61747572653a20636875726e417070726f766572606482015271081cda59db985d1d5c9948195e1c1a5c995960721b608482015260a401610849565b602080820180516000908152609a909252604091829020805460ff19166001179055609d54905191830151610930926001600160a01b03909216916130ca91889188918891906117a8565b8351614221565b6130f560405180606001604052806060815260200160608152602001606081525090565b600061313d86868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060965460ff1691506128119050565b9050600061314a886122db565b90506001600160c01b0382166131c85760405162461bcd60e51b815260206004820152603960248201527f5265676973747279436f6f7264696e61746f722e5f72656769737465724f706560448201527f7261746f723a206269746d61702063616e6e6f742062652030000000000000006064820152608401610849565b8082166001600160c01b03161561327e5760405162461bcd60e51b815260206004820152606860248201527f5265676973747279436f6f7264696e61746f722e5f72656769737465724f706560448201527f7261746f723a206f70657261746f7220616c726561647920726567697374657260648201527f656420666f7220736f6d652071756f72756d73206265696e672072656769737460848201526732b932b2103337b960c11b60a482015260c401610849565b6001600160c01b03818116908316176132978982614061565b887fec2963ab21c1e50e1e582aa542af2e4bf7bf38e6e1403c27b42e1c5d6e621eaa876040516132c791906155fa565b60405180910390a260016001600160a01b038b1660009081526099602052604090206001015460ff16600281111561330157613301614be3565b1461341a576040805180820182528a8152600160208083018281526001600160a01b038f166000908152609990925293902082518155925183820180549394939192909160ff19169083600281111561335c5761335c614be3565b021790555050604051639926ee7d60e01b81526001600160a01b037f00000000000000000000000084ea74d481ee0a5332c457a4d796187f6ba67feb169150639926ee7d906133b1908d908990600401615996565b600060405180830381600087803b1580156133cb57600080fd5b505af11580156133df573d6000803e3d6000fd5b50506040518b92506001600160a01b038d1691507fe8e68cef1c3a761ed7be7e8463a375f27f7bc335e51824223cacce636ec5c3fe90600090a35b604051631fd93ca960e11b81526001600160a01b037f0000000000000000000000001613beb3b2c4f22ee086b2b38c1476a3ce7f78e81690633fb279529061346a908d908c908c90600401615a0a565b600060405180830381600087803b15801561348457600080fd5b505af1158015613498573d6000803e3d6000fd5b5050604051632550477760e01b81526001600160a01b037f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f36169250632550477791506134ee908d908d908d908d90600401615a2f565b6000604051808303816000875af115801561350d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526135359190810190615abb565b60408087019190915260208601919091525162bff04d60e01b81526001600160a01b037f000000000000000000000000851356ae760d987e095750cceb3bc6014560891c169062bff04d90613592908c908c908c90600401615b1e565b6000604051808303816000875af11580156135b1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526135d99190810190615b38565b84525050509695505050505050565b6020808301516001600160a01b0380821660008181526099909452604090932054919290871614156136685760405162461bcd60e51b81526020600482015260356024820152600080516020615d4e83398151915260448201527439371d1031b0b73737ba1031b43ab9371039b2b63360591b6064820152608401610849565b8760ff16846000015160ff16146136e55760405162461bcd60e51b81526020600482015260476024820152600080516020615d4e83398151915260448201527f726e3a2071756f72756d4e756d626572206e6f74207468652073616d65206173606482015266081cda59db995960ca1b608482015260a401610849565b604051635401ed2760e01b81526004810182905260ff891660248201526000907f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f366001600160a01b031690635401ed2790604401602060405180830381865afa158015613756573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061377a9190615bd1565b905061378681856143db565b6001600160601b0316866001600160601b0316116138195760405162461bcd60e51b81526020600482015260566024820152600080516020615d4e83398151915260448201527f726e3a20696e636f6d696e67206f70657261746f722068617320696e7375666660648201527534b1b4b2b73a1039ba30b5b2903337b91031b43ab93760511b608482015260a401610849565b61382388856143ff565b6001600160601b0316816001600160601b0316106120fe5760405162461bcd60e51b815260206004820152605c6024820152600080516020615d4e83398151915260448201527f726e3a2063616e6e6f74206b69636b206f70657261746f722077697468206d6f60648201527f7265207468616e206b69636b424950734f66546f74616c5374616b6500000000608482015260a401610849565b600081815260986020526040812054815b8181101561394f5760016138e28284615827565b6138ec9190615827565b92508463ffffffff16609860008681526020019081526020016000208463ffffffff168154811061391f5761391f615566565b60009182526020909120015463ffffffff161161393d575050610e8f565b8061394781615592565b9150506138ce565b5060405162461bcd60e51b815260206004820152606c60248201527f5265676973747279436f6f7264696e61746f722e67657451756f72756d42697460448201527f6d6170496e6465784174426c6f636b4e756d6265723a206e6f206269746d617060648201527f2075706461746520666f756e6420666f72206f70657261746f7249642061742060848201526b313637b1b590373ab6b132b960a11b60a482015260c401610849565b60965460ff1660c08110613a6d5760405162461bcd60e51b815260206004820152603560248201527f5265676973747279436f6f7264696e61746f722e63726561746551756f72756d6044820152740e881b585e081c5d5bdc9d5b5cc81c995858da1959605a1b6064820152608401610849565b613a78816001615bee565b6096805460ff191660ff9290921691909117905580613a9781866128a2565b60405160016296b58960e01b031981526001600160a01b037f000000000000000000000000f5059a5d33d5853360d16c683c16e67980206f36169063ff694a7790613aea90849088908890600401615c13565b600060405180830381600087803b158015613b0457600080fd5b505af1158015613b18573d6000803e3d6000fd5b505060405163136ca0f960e11b815260ff841660048201527f000000000000000000000000851356ae760d987e095750cceb3bc6014560891c6001600160a01b031692506326d941f29150602401600060405180830381600087803b158015613b8057600080fd5b505af1158015613b94573d6000803e3d6000fd5b505060405163136ca0f960e11b815260ff841660048201527f0000000000000000000000001613beb3b2c4f22ee086b2b38c1476a3ce7f78e86001600160a01b031692506326d941f29150602401600060405180830381600087803b158015613bfc57600080fd5b505af11580156120fe573d6000803e3d6000fd5b6000546201000090046001600160a01b0316158015613c3757506001600160a01b03821615155b613cb95760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610849565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2613cfc826124fd565b5050565b6000805b8215610e8f57613d15600184615827565b9092169180613d2381615c8c565b915050613d04565b6000306001600160a01b037f0000000000000000000000009d4454b023096f34b160d6b654540c56a1f8168816148015613d8457507f0000000000000000000000000000000000000000000000000000000000007a6946145b15613dae57507f56a163e88e401072adbbeeab39218565e56ef380e0e80783073a63479602f01a90565b50604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f6ec8a99f0e7f9ebde7354a446dcb9423f3af9c58f386a53c59c5b384f9e82d11828401527f6bda7e3f385e48841048390444cced5cc795af87758af67622e5f4f0882c4a9960608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60008080600080516020615d6e8339815191526003600080516020615d6e83398151915286600080516020615d6e833981519152888909090890506000613ec8827f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52600080516020615d6e833981519152614419565b91959194509092505050565b600061010082511115613f5d5760405162461bcd60e51b8152602060048201526044602482018190527f4269746d61705574696c732e6f72646572656442797465734172726179546f42908201527f69746d61703a206f7264657265644279746573417272617920697320746f6f206064820152636c6f6e6760e01b608482015260a401610849565b8151613f6b57506000919050565b60008083600081518110613f8157613f81615566565b0160200151600160f89190911c81901b92505b845181101561405857848181518110613faf57613faf615566565b0160200151600160f89190911c1b91508282116140445760405162461bcd60e51b815260206004820152604760248201527f4269746d61705574696c732e6f72646572656442797465734172726179546f4260448201527f69746d61703a206f72646572656442797465734172726179206973206e6f74206064820152661bdc99195c995960ca1b608482015260a401610849565b9181179161405181615592565b9050613f94565b50909392505050565b60008281526098602052604090205480614106576000838152609860209081526040808320815160608101835263ffffffff43811682528185018681526001600160c01b03808a16958401958652845460018101865594885295909620915191909201805495519351909416600160401b026001600160401b03938316600160201b0267ffffffffffffffff1990961691909216179390931716919091179055505050565b600083815260986020526040812061411f600184615827565b8154811061412f5761412f615566565b600091825260209091200180549091504363ffffffff908116911614156141735780546001600160401b0316600160401b6001600160c01b03851602178155610930565b805463ffffffff438116600160201b81810267ffffffff0000000019909416939093178455600087815260986020908152604080832081516060810183529485528483018481526001600160c01b03808c1693870193845282546001810184559286529390942094519401805493519151909216600160401b026001600160401b0391861690960267ffffffffffffffff199093169390941692909217179190911691909117905550505050565b6001600160a01b0383163b1561433b57604051630b135d3f60e11b808252906001600160a01b03851690631626ba7e9061426190869086906004016158e5565b602060405180830381865afa15801561427e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142a29190615cae565b6001600160e01b031916146116a55760405162461bcd60e51b815260206004820152605360248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a2045524331323731207369676e6174757265206064820152721d995c9a599a58d85d1a5bdb8819985a5b1959606a1b608482015260a401610849565b826001600160a01b031661434f83836144c8565b6001600160a01b0316146116a55760405162461bcd60e51b815260206004820152604760248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a207369676e6174757265206e6f742066726f6d6064820152661039b4b3b732b960c91b608482015260a401610849565b6020810151600090612710906143f59061ffff1685615cd8565b61289b9190615d07565b6040810151600090612710906143f59061ffff1685615cd8565b600080614424614835565b61442c614853565b602080825281810181905260408201819052606082018890526080820187905260a082018690528260c08360056107d05a03fa925082801561446d5761446f565bfe5b50826144bd5760405162461bcd60e51b815260206004820152601a60248201527f424e3235342e6578704d6f643a2063616c6c206661696c7572650000000000006044820152606401610849565b505195945050505050565b60008060006144d785856144e4565b91509150611d8381614554565b60008082516041141561451b5760208301516040840151606085015160001a61450f8782858561470f565b9450945050505061454d565b825160401415614545576020830151604084015161453a8683836147fc565b93509350505061454d565b506000905060025b9250929050565b600081600481111561456857614568614be3565b14156145715750565b600181600481111561458557614585614be3565b14156145d35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610849565b60028160048111156145e7576145e7614be3565b14156146355760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610849565b600381600481111561464957614649614be3565b14156146a25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610849565b60048160048111156146b6576146b6614be3565b1415610cc45760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610849565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561474657506000905060036147f3565b8460ff16601b1415801561475e57508460ff16601c14155b1561476f57506000905060046147f3565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156147c3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166147ec576000600192509250506147f3565b9150600090505b94509492505050565b6000806001600160ff1b0383168161481960ff86901c601b615744565b90506148278782888561470f565b935093505050935093915050565b60405180602001604052806001906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60008083601f84011261488357600080fd5b5081356001600160401b0381111561489a57600080fd5b6020830191508360208260051b850101111561454d57600080fd5b600080602083850312156148c857600080fd5b82356001600160401b038111156148de57600080fd5b6148ea85828601614871565b90969095509350505050565b60006020828403121561490857600080fd5b5035919050565b63ffffffff81168114610cc457600080fd5b60008060006060848603121561493657600080fd5b8335925060208401356149488161490f565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b038111828210171561499157614991614959565b60405290565b604080519081016001600160401b038111828210171561499157614991614959565b604051601f8201601f191681016001600160401b03811182821017156149e1576149e1614959565b604052919050565b60006001600160401b03831115614a0257614a02614959565b614a15601f8401601f19166020016149b9565b9050828152838383011115614a2957600080fd5b828260208301376000602084830101529392505050565b600060208284031215614a5257600080fd5b81356001600160401b03811115614a6857600080fd5b8201601f81018413614a7957600080fd5b614a88848235602084016149e9565b949350505050565b6001600160a01b0381168114610cc457600080fd5b8035614ab081614a90565b919050565b600060208284031215614ac757600080fd5b813561289b81614a90565b60008060408385031215614ae557600080fd5b50508035926020909101359150565b803560ff81168114614ab057600080fd5b600060208284031215614b1757600080fd5b61289b82614af4565b815181526020808301519082015260408101610e8f565b60008083601f840112614b4957600080fd5b5081356001600160401b03811115614b6057600080fd5b60208301915083602082850101111561454d57600080fd5b60008060008060408587031215614b8e57600080fd5b84356001600160401b0380821115614ba557600080fd5b614bb188838901614871565b90965094506020870135915080821115614bca57600080fd5b50614bd787828801614b37565b95989497509550505050565b634e487b7160e01b600052602160045260246000fd5b60038110614c1757634e487b7160e01b600052602160045260246000fd5b9052565b815181526020808301516040830191614c3690840182614bf9565b5092915050565b803561ffff81168114614ab057600080fd5b600060608284031215614c6157600080fd5b614c6961496f565b90508135614c768161490f565b8152614c8460208301614c3d565b6020820152614c9560408301614c3d565b604082015292915050565b60008060808385031215614cb357600080fd5b614cbc83614af4565b9150614ccb8460208501614c4f565b90509250929050565b600080600060408486031215614ce957600080fd5b8335614cf481614a90565b925060208401356001600160401b03811115614d0f57600080fd5b614d1b86828701614b37565b9497909650939450505050565b60006001600160401b03821115614d4157614d41614959565b5060051b60200190565b600060408284031215614d5d57600080fd5b614d65614997565b9050614d7082614af4565b81526020820135614d8081614a90565b602082015292915050565b600080600080600060a08688031215614da357600080fd5b8535614dae81614a90565b945060208681013594506040808801356001600160401b03811115614dd257600080fd5b8801601f81018a13614de357600080fd5b8035614df6614df182614d28565b6149b9565b81815260069190911b8201840190848101908c831115614e1557600080fd5b928501925b82841015614e3b57614e2c8d85614d4b565b82529284019290850190614e1a565b999c989b5098996060810135995060800135979650505050505050565b60006101008284031215614e6b57600080fd5b50919050565b60008083601f840112614e8357600080fd5b5081356001600160401b03811115614e9a57600080fd5b6020830191508360208260061b850101111561454d57600080fd5b600060608284031215614ec757600080fd5b614ecf61496f565b905081356001600160401b03811115614ee757600080fd5b8201601f81018413614ef857600080fd5b614f07848235602084016149e9565b825250602082013560208201526040820135604082015292915050565b60008060008060008060008060006101a08a8c031215614f4357600080fd5b89356001600160401b0380821115614f5a57600080fd5b614f668d838e01614b37565b909b50995060208c0135915080821115614f7f57600080fd5b614f8b8d838e01614b37565b9099509750879150614fa08d60408e01614e58565b96506101408c0135915080821115614fb757600080fd5b614fc38d838e01614e71565b90965094506101608c0135915080821115614fdd57600080fd5b614fe98d838e01614eb5565b93506101808c013591508082111561500057600080fd5b5061500d8c828d01614eb5565b9150509295985092959850929598565b600080600080600080610160878903121561503757600080fd5b86356001600160401b038082111561504e57600080fd5b61505a8a838b01614b37565b9098509650602089013591508082111561507357600080fd5b61507f8a838b01614b37565b90965094508491506150948a60408b01614e58565b93506101408901359150808211156150ab57600080fd5b506150b889828a01614eb5565b9150509295509295509295565b600080604083850312156150d857600080fd5b82356150e38161490f565b91506020838101356001600160401b038111156150ff57600080fd5b8401601f8101861361511057600080fd5b803561511e614df182614d28565b81815260059190911b8201830190838101908883111561513d57600080fd5b928401925b8284101561515b57833582529284019290840190615142565b80955050505050509250929050565b6020808252825182820181905260009190848201906040850190845b818110156151a857835163ffffffff1683529284019291840191600101615186565b50909695505050505050565b600080602083850312156151c757600080fd5b82356001600160401b038111156151dd57600080fd5b6148ea85828601614b37565b6001600160601b0381168114610cc457600080fd5b600082601f83011261520f57600080fd5b8135602061521f614df183614d28565b82815260069290921b8401810191818101908684111561523e57600080fd5b8286015b8481101561528f576040818903121561525b5760008081fd5b615263614997565b813561526e81614a90565b81528185013561527d816151e9565b81860152835291830191604001615242565b509695505050505050565b600080600060a084860312156152af57600080fd5b6152b98585614c4f565b925060608401356152c9816151e9565b915060808401356001600160401b038111156152e457600080fd5b6152f0868287016151fe565b9150509250925092565b600082601f83011261530b57600080fd5b8135602061531b614df183614d28565b8281526060928302850182019282820191908785111561533a57600080fd5b8387015b8581101561535d576153508982614c4f565b845292840192810161533e565b5090979650505050505050565b600082601f83011261537b57600080fd5b8135602061538b614df183614d28565b82815260059290921b840181019181810190868411156153aa57600080fd5b8286015b8481101561528f5780356153c1816151e9565b83529183019183016153ae565b600082601f8301126153df57600080fd5b813560206153ef614df183614d28565b82815260059290921b8401810191818101908684111561540e57600080fd5b8286015b8481101561528f5780356001600160401b038111156154315760008081fd5b61543f8986838b01016151fe565b845250918301918301615412565b600080600080600080600080610100898b03121561546a57600080fd5b61547389614aa5565b975061548160208a01614aa5565b965061548f60408a01614aa5565b955061549d60608a01614aa5565b94506080890135935060a08901356001600160401b03808211156154c057600080fd5b6154cc8c838d016152fa565b945060c08b01359150808211156154e257600080fd5b6154ee8c838d0161536a565b935060e08b013591508082111561550457600080fd5b506155118b828c016153ce565b9150509295985092959890939650565b60208101610e8f8284614bf9565b60208082526019908201527f5061757361626c653a20696e6465782069732070617573656400000000000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156155a6576155a661557c565b5060010190565b6000815180845260005b818110156155d3576020818501810151868301820152016155b7565b818111156155e5576000602083870101525b50601f01601f19169290920160200192915050565b60208152600061289b60208301846155ad565b60006020828403121561561f57600080fd5b815161289b81614a90565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b60006020828403121561568657600080fd5b8151801515811461289b57600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b6000808335601e198436030181126156f557600080fd5b8301803591506001600160401b0382111561570f57600080fd5b6020019150600581901b360382131561454d57600080fd5b60006020828403121561573957600080fd5b815161289b8161490f565b600082198211156157575761575761557c565b500190565b6000808585111561576c57600080fd5b8386111561577957600080fd5b5050820193919092039150565b600060c08201888352602060018060a01b03808a16828601526040898187015260c0606087015283895180865260e088019150848b01955060005b818110156157eb578651805160ff16845286015185168684015295850195918301916001016157c1565b505060808701989098525050505060a09091019190915250949350505050565b60006040828403121561581d57600080fd5b61289b8383614d4b565b6000828210156158395761583961557c565b500390565b60018060a01b038416815282602082015260606040820152600061586560608301846155ad565b95945050505050565b60006020828403121561588057600080fd5b81516001600160c01b038116811461289b57600080fd5b634e487b7160e01b600052601260045260246000fd5b6000826158bc576158bc615897565b500690565b6001600160a01b0383168152604060208201819052600090614a88908301846155ad565b828152604060208201526000614a8860408301846155ad565b60006020828403121561591057600080fd5b5051919050565b6001600160a01b0384168152610160810161593f602083018580358252602090810135910152565b615959606083016040860180358252602090810135910152565b60406080850160a084013760e0820160008152604060c0860182375060006101208301908152835190526020909201516101409091015292915050565b60018060a01b03831681526040602082015260008251606060408401526159c060a08401826155ad565b90506020840151606084015260408401516080840152809150509392505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b038416815260406020820181905260009061586590830184866159e1565b60018060a01b03851681528360208201526060604082015260006117e86060830184866159e1565b600082601f830112615a6857600080fd5b81516020615a78614df183614d28565b82815260059290921b84018101918181019086841115615a9757600080fd5b8286015b8481101561528f578051615aae816151e9565b8352918301918301615a9b565b60008060408385031215615ace57600080fd5b82516001600160401b0380821115615ae557600080fd5b615af186838701615a57565b93506020850151915080821115615b0757600080fd5b50615b1485828601615a57565b9150509250929050565b8381526040602082015260006158656040830184866159e1565b60006020808385031215615b4b57600080fd5b82516001600160401b03811115615b6157600080fd5b8301601f81018513615b7257600080fd5b8051615b80614df182614d28565b81815260059190911b82018301908381019087831115615b9f57600080fd5b928401925b82841015615bc6578351615bb78161490f565b82529284019290840190615ba4565b979650505050505050565b600060208284031215615be357600080fd5b815161289b816151e9565b600060ff821660ff84168060ff03821115615c0b57615c0b61557c565b019392505050565b60006060820160ff8616835260206001600160601b03808716828601526040606081870152838751808652608088019150848901955060005b81811015615c7c57865180516001600160a01b031684528601518516868401529585019591830191600101615c4c565b50909a9950505050505050505050565b600061ffff80831681811415615ca457615ca461557c565b6001019392505050565b600060208284031215615cc057600080fd5b81516001600160e01b03198116811461289b57600080fd5b60006001600160601b0380831681851681830481118215151615615cfe57615cfe61557c565b02949350505050565b60006001600160601b0380841680615d2157615d21615897565b9216919091049291505056fe5265676973747279436f6f7264696e61746f722e7570646174654f70657261745265676973747279436f6f7264696e61746f722e5f76616c696461746543687530644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47a26469706673582212202b86dea51bfb4bb72d359d31891d9e4fa87805cc66a1ee1ad9d226546740631064736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x9e545e3c0baab3e08cdfd552c960a1050f373042":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122007c3990e071012e67e928be8d71cb1c6b5ed96fee92e98c9e70cc231dee7232064736f6c634300080c0033","storage":{"0x0":"0x1","0x33":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x65":"0xe6e340d132b5f46d1e472debcd681b2abc16e57e","0x66":"0x0","0xcd":"0xa0ee7a142d267c1f36714e4a8f75612f20a79720","0xce":"0xa0ee7a142d267c1f36714e4a8f75612f20a79720","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x4c5859f0f772848b2d91f1d83e2fe57935348029","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x67d269191c92caf3cd7723f116c85e6e9bf55933"}},"0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0":{"nonce":1,"balance":"0x0","code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b600060405190815260200160405180910390f3fea26469706673582212205c7f5f91a0325be43155eb5cb04c77befb735a5810f8939de23702c1530cc5f564736f6c634300080c0033","storage":{}},"0xa0ee7a142d267c1f36714e4a8f75612f20a79720":{"nonce":1,"balance":"0x21d8f199d30a6172050","code":"0x","storage":{}},"0xa513e6e4b8f2a923d98304ec87f64353c4d5c853":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033","storage":{"0x0":"0x1","0x33":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x65":"0xe7f1725e7734ce288f8367e1bb143e90bb3f0512","0x66":"0x1e","0x97":"0x0","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0xb306bf915c4d645ff596e518faf3f9669b97016","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0xa51c1fc2f0d1a1b8494ed1fe312d7c3a78ed91c0":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106102275760003560e01c806394f649dd11610130578063c6656702116100b8578063df5cf7231161007c578063df5cf72314610596578063e7a050aa146105bd578063f2fde38b146105d0578063f698da25146105e3578063fabc1cbc146105eb57600080fd5b8063c665670214610520578063cbc2bd6214610533578063cd293f6f14610546578063cf756fdf14610570578063df5b35471461058357600080fd5b8063b43b514b116100ff578063b43b514b146104b1578063b5d8b5b8146104c4578063c3c6b3a9146104d7578063c4623ea1146104fa578063c608c7f31461050d57600080fd5b806394f649dd14610433578063967fc0d2146104545780639b4da03d14610467578063b13442711461048a57600080fd5b80635c975abb116101b35780637ecebe00116101825780637ecebe00146103b3578063886f1195146103d35780638b8aac3c146103e65780638c80d4e51461040f5780638da5cb5b1461042257600080fd5b80635c975abb14610355578063663c1de41461035d578063715018a6146103805780637a7e0d921461038857600080fd5b80634665bcda116101fa5780634665bcda146102a157806348825e94146102e05780634e5a426314610307578063595c6a671461031a5780635ac86ab71461032257600080fd5b806310d67a2f1461022c578063136439dd1461024157806320606b701461025457806332e89ace1461028e575b600080fd5b61023f61023a366004612b4a565b6105fe565b005b61023f61024f366004612b67565b6106ba565b61027b7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6040519081526020015b60405180910390f35b61027b61029c366004612c00565b6107f9565b6102c87f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85381565b6040516001600160a01b039091168152602001610285565b61027b7f4337f82d142e41f2a8c10547cd8c859bddb92262a61058e77842e24d9dea922481565b61023f610315366004612ced565b610ae7565b61023f610b1f565b610345610330366004612d26565b609854600160ff9092169190911b9081161490565b6040519015158152602001610285565b60985461027b565b61034561036b366004612b4a565b60d16020526000908152604090205460ff1681565b61023f610be6565b61027b610396366004612d49565b60cd60209081526000928352604080842090915290825290205481565b61027b6103c1366004612b4a565b60ca6020526000908152604090205481565b6097546102c8906001600160a01b031681565b61027b6103f4366004612b4a565b6001600160a01b0316600090815260ce602052604090205490565b61023f61041d366004612d77565b610bfa565b6033546001600160a01b03166102c8565b610446610441366004612b4a565b610c53565b604051610285929190612e2c565b60cb546102c8906001600160a01b031681565b610345610475366004612b4a565b60d36020526000908152604090205460ff1681565b6102c87f0000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f81565b61027b6104bf366004612fd5565b610dd3565b61023f6104d23660046130f0565b610e20565b6103456104e5366004612b67565b60cf6020526000908152604090205460ff1681565b61023f610508366004613132565b610f94565b61023f61051b366004613183565b610fe8565b61023f61052e366004612b4a565b6110a0565b6102c86105413660046131d6565b6110b1565b610559610554366004612fd5565b6110e9565b604080519215158352602083019190915201610285565b61023f61057e366004613132565b61117d565b61023f610591366004613202565b6112b1565b6102c87f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc981565b61027b6105cb366004612d77565b6114da565b61023f6105de366004612b4a565b6115a3565b61027b611619565b61023f6105f9366004612b67565b611657565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610651573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610675919061326e565b6001600160a01b0316336001600160a01b0316146106ae5760405162461bcd60e51b81526004016106a59061328b565b60405180910390fd5b6106b7816117b3565b50565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610702573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072691906132d5565b6107425760405162461bcd60e51b81526004016106a5906132f2565b609854818116146107bb5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c697479000000000000000060648201526084016106a5565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6098546000908190600190811614156108505760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b60448201526064016106a5565b600260655414156108a35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106a5565b60026065556001600160a01b038816600090815260d3602052604090205460ff161561094a5760405162461bcd60e51b815260206004820152604a60248201527f53747261746567794d616e616765722e6465706f736974496e746f537472617460448201527f656779576974685369676e61747572653a207468697264207472616e736665726064820152691cc8191a5cd8589b195960b21b608482015260a4016106a5565b428410156109cc5760405162461bcd60e51b815260206004820152604360248201527f53747261746567794d616e616765722e6465706f736974496e746f537472617460448201527f656779576974685369676e61747572653a207369676e617475726520657870696064820152621c995960ea1b608482015260a4016106a5565b6001600160a01b03858116600081815260ca602090815260408083205481517f4337f82d142e41f2a8c10547cd8c859bddb92262a61058e77842e24d9dea922493810193909352908201939093528b84166060820152928a16608084015260a0830189905260c0830182905260e0830187905290916101000160408051601f1981840301815291815281516020928301206001600160a01b038a16600090815260ca9093529082206001850190559150610a84611619565b60405161190160f01b6020820152602281019190915260428101839052606201604051602081830303815290604052805190602001209050610ac78882886118aa565b610ad3888c8c8c611a69565b60016065559b9a5050505050505050505050565b60cb546001600160a01b03163314610b115760405162461bcd60e51b81526004016106a59061333a565b610b1b8282611c38565b5050565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610b67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8b91906132d5565b610ba75760405162461bcd60e51b81526004016106a5906132f2565b600019609881905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b610bee611ca6565b610bf86000611d00565b565b336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc91614610c425760405162461bcd60e51b81526004016106a5906133a4565b610c4d838383611d52565b50505050565b6001600160a01b038116600090815260ce60205260408120546060918291908167ffffffffffffffff811115610c8b57610c8b612b90565b604051908082528060200260200182016040528015610cb4578160200160208202803683370190505b50905060005b82811015610d45576001600160a01b038616600090815260cd6020908152604080832060ce9092528220805491929184908110610cf957610cf9613402565b60009182526020808320909101546001600160a01b031683528201929092526040019020548251839083908110610d3257610d32613402565b6020908102919091010152600101610cba565b5060ce6000866001600160a01b03166001600160a01b031681526020019081526020016000208181805480602002602001604051908101604052809291908181526020018280548015610dc157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610da3575b50505050509150935093505050915091565b80516020808301516040808501516060860151608087015160a08801519351600097610e03979096959101613418565b604051602081830303815290604052805190602001209050919050565b60cb546001600160a01b03163314610e4a5760405162461bcd60e51b81526004016106a59061333a565b8060005b81811015610c4d5760d16000858584818110610e6c57610e6c613402565b9050602002016020810190610e819190612b4a565b6001600160a01b0316815260208101919091526040016000205460ff1615610f8c57600060d16000868685818110610ebb57610ebb613402565b9050602002016020810190610ed09190612b4a565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f4074413b4b443e4e58019f2855a8765113358c7c72e39509c6af45fc0f5ba030848483818110610f2b57610f2b613402565b9050602002016020810190610f409190612b4a565b6040516001600160a01b03909116815260200160405180910390a1610f8c848483818110610f7057610f70613402565b9050602002016020810190610f859190612b4a565b6000611c38565b600101610e4e565b336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc91614610fdc5760405162461bcd60e51b81526004016106a5906133a4565b610c4d84848484611eae565b336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc916146110305760405162461bcd60e51b81526004016106a5906133a4565b604051636ce5768960e11b81526001600160a01b03858116600483015282811660248301526044820184905284169063d9caed1290606401600060405180830381600087803b15801561108257600080fd5b505af1158015611096573d6000803e3d6000fd5b5050505050505050565b6110a8611ca6565b6106b78161213b565b60ce60205281600052604060002081815481106110cd57600080fd5b6000918252602090912001546001600160a01b03169150829050565b600080336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc916146111345760405162461bcd60e51b81526004016106a5906133a4565b600061113f84610dd3565b600081815260cf60205260408120549192509060ff16156111745750600081815260cf60205260409020805460ff1916905560015b92509050915091565b600054610100900460ff161580801561119d5750600054600160ff909116105b806111b75750303b1580156111b7575060005460ff166001145b61121a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106a5565b6000805460ff19166001179055801561123d576000805461ff0019166101001790555b6112456121a4565b60c955611252838361223b565b61125b85611d00565b6112648461213b565b80156112aa576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60cb546001600160a01b031633146112db5760405162461bcd60e51b81526004016106a59061333a565b8281146113645760405162461bcd60e51b815260206004820152604b60248201527f53747261746567794d616e616765722e61646453747261746567696573546f4460448201527f65706f73697457686974656c6973743a206172726179206c656e67746873206460648201526a0de40dcdee840dac2e8c6d60ab1b608482015260a4016106a5565b8260005b818110156114d25760d1600087878481811061138657611386613402565b905060200201602081019061139b9190612b4a565b6001600160a01b0316815260208101919091526040016000205460ff166114ca57600160d160008888858181106113d4576113d4613402565b90506020020160208101906113e99190612b4a565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f0c35b17d91c96eb2751cd456e1252f42a386e524ef9ff26ecc9950859fdc04fe86868381811061144457611444613402565b90506020020160208101906114599190612b4a565b6040516001600160a01b03909116815260200160405180910390a16114ca86868381811061148957611489613402565b905060200201602081019061149e9190612b4a565b8585848181106114b0576114b0613402565b90506020020160208101906114c59190613491565b611c38565b600101611368565b505050505050565b6098546000908190600190811614156115315760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b60448201526064016106a5565b600260655414156115845760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106a5565b600260655561159533868686611a69565b600160655595945050505050565b6115ab611ca6565b6001600160a01b0381166116105760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016106a5565b6106b781611d00565b60007f0000000000000000000000000000000000000000000000000000000000007a6946141561164a575060c95490565b6116526121a4565b905090565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ce919061326e565b6001600160a01b0316336001600160a01b0316146116fe5760405162461bcd60e51b81526004016106a59061328b565b60985419811960985419161461177c5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c697479000000000000000060648201526084016106a5565b609881905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c906020016107ee565b6001600160a01b0381166118415760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a4016106a5565b609754604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1609780546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0383163b156119c957604051630b135d3f60e11b808252906001600160a01b03851690631626ba7e906118ea9086908690600401613506565b602060405180830381865afa158015611907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192b919061351f565b6001600160e01b031916146119c45760405162461bcd60e51b815260206004820152605360248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a2045524331323731207369676e6174757265206064820152721d995c9a599a58d85d1a5bdb8819985a5b1959606a1b608482015260a4016106a5565b505050565b826001600160a01b03166119dd8383612321565b6001600160a01b0316146119c45760405162461bcd60e51b815260206004820152604760248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a207369676e6174757265206e6f742066726f6d6064820152661039b4b3b732b960c91b608482015260a4016106a5565b6001600160a01b038316600090815260d16020526040812054849060ff16611b0f5760405162461bcd60e51b815260206004820152604d60248201527f53747261746567794d616e616765722e6f6e6c7953747261746567696573576860448201527f6974656c6973746564466f724465706f7369743a207374726174656779206e6f60648201526c1d081dda1a5d195b1a5cdd1959609a1b608482015260a4016106a5565b611b246001600160a01b038516338786612345565b6040516311f9fbc960e21b81526001600160a01b038581166004830152602482018590528616906347e7ef24906044016020604051808303816000875af1158015611b73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b979190613549565b9150611ba586858785611eae565b604051631452b9d760e11b81526001600160a01b0387811660048301528681166024830152604482018490527f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc916906328a573ae90606401600060405180830381600087803b158015611c1757600080fd5b505af1158015611c2b573d6000803e3d6000fd5b5050505050949350505050565b604080516001600160a01b038416815282151560208201527f77d930df4937793473a95024d87a98fd2ccb9e92d3c2463b3dacd65d3e6a5786910160405180910390a16001600160a01b0391909116600090815260d360205260409020805460ff1916911515919091179055565b6033546001600160a01b03163314610bf85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106a5565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600081611dc75760405162461bcd60e51b815260206004820152603e60248201527f53747261746567794d616e616765722e5f72656d6f76655368617265733a207360448201527f68617265416d6f756e742073686f756c64206e6f74206265207a65726f21000060648201526084016106a5565b6001600160a01b03808516600090815260cd602090815260408083209387168352929052205480831115611e595760405162461bcd60e51b815260206004820152603360248201527f53747261746567794d616e616765722e5f72656d6f76655368617265733a20736044820152720d0c2e4ca82dadeeadce840e8dede40d0d2ced606b1b60648201526084016106a5565b6001600160a01b03808616600090815260cd602090815260408083209388168352929052208382039081905590831415611ea157611e97858561239f565b6001915050611ea7565b60009150505b9392505050565b6001600160a01b038416611f2a5760405162461bcd60e51b815260206004820152603960248201527f53747261746567794d616e616765722e5f6164645368617265733a207374616b60448201527f65722063616e6e6f74206265207a65726f20616464726573730000000000000060648201526084016106a5565b80611f965760405162461bcd60e51b815260206004820152603660248201527f53747261746567794d616e616765722e5f6164645368617265733a207368617260448201527565732073686f756c64206e6f74206265207a65726f2160501b60648201526084016106a5565b6001600160a01b03808516600090815260cd60209081526040808320938616835292905220546120a7576001600160a01b038416600090815260ce6020908152604090912054106120685760405162461bcd60e51b815260206004820152605060248201527f53747261746567794d616e616765722e5f6164645368617265733a206465706f60448201527f73697420776f756c6420657863656564204d41585f5354414b45525f5354524160648201526f0a88a8eb2be9892a6a8be988a9c8ea8960831b608482015260a4016106a5565b6001600160a01b03848116600090815260ce602090815260408220805460018101825590835291200180546001600160a01b0319169184169190911790555b6001600160a01b03808516600090815260cd60209081526040808320938616835292905290812080548392906120de908490613578565b9091555050604080516001600160a01b03868116825285811660208301528416818301526060810183905290517f7cfff908a4b583f36430b25d75964c458d8ede8a99bd61be750e97ee1b2f3a969181900360800190a150505050565b60cb54604080516001600160a01b03928316815291831660208301527f4264275e593955ff9d6146a51a4525f6ddace2e81db9391abcc9d1ca48047d29910160405180910390a160cb80546001600160a01b0319166001600160a01b0392909216919091179055565b604080518082018252600a81526922b4b3b2b72630bcb2b960b11b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f71b625cfad44bac63b13dba07f2e1d6084ee04b6f8752101ece6126d584ee6ea81840152466060820152306080808301919091528351808303909101815260a0909101909252815191012090565b6097546001600160a01b031615801561225c57506001600160a01b03821615155b6122de5760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a4016106a5565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2610b1b826117b3565b60008060006123308585612591565b9150915061233d81612601565b509392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610c4d9085906127bc565b6001600160a01b038216600090815260ce6020526040812054905b818110156124ba576001600160a01b03848116600090815260ce60205260409020805491851691839081106123f1576123f1613402565b6000918252602090912001546001600160a01b031614156124b2576001600160a01b038416600090815260ce60205260409020805461243290600190613590565b8154811061244257612442613402565b60009182526020808320909101546001600160a01b03878116845260ce909252604090922080549190921691908390811061247f5761247f613402565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506124ba565b6001016123ba565b818114156125425760405162461bcd60e51b815260206004820152604960248201527f53747261746567794d616e616765722e5f72656d6f766553747261746567794660448201527f726f6d5374616b657253747261746567794c6973743a207374726174656779206064820152681b9bdd08199bdd5b9960ba1b608482015260a4016106a5565b6001600160a01b038416600090815260ce60205260409020805480612569576125696135a7565b600082815260209020810160001990810180546001600160a01b031916905501905550505050565b6000808251604114156125c85760208301516040840151606085015160001a6125bc8782858561288e565b945094505050506125fa565b8251604014156125f257602083015160408401516125e786838361297b565b9350935050506125fa565b506000905060025b9250929050565b6000816004811115612615576126156135bd565b141561261e5750565b6001816004811115612632576126326135bd565b14156126805760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016106a5565b6002816004811115612694576126946135bd565b14156126e25760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016106a5565b60038160048111156126f6576126f66135bd565b141561274f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016106a5565b6004816004811115612763576127636135bd565b14156106b75760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016106a5565b6000612811826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166129b49092919063ffffffff16565b8051909150156119c4578080602001905181019061282f91906132d5565b6119c45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016106a5565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156128c55750600090506003612972565b8460ff16601b141580156128dd57508460ff16601c14155b156128ee5750600090506004612972565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612942573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661296b57600060019250925050612972565b9150600090505b94509492505050565b6000806001600160ff1b0383168161299860ff86901c601b613578565b90506129a68782888561288e565b935093505050935093915050565b60606129c384846000856129cb565b949350505050565b606082471015612a2c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016106a5565b6001600160a01b0385163b612a835760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106a5565b600080866001600160a01b03168587604051612a9f91906135d3565b60006040518083038185875af1925050503d8060008114612adc576040519150601f19603f3d011682016040523d82523d6000602084013e612ae1565b606091505b5091509150612af1828286612afc565b979650505050505050565b60608315612b0b575081611ea7565b825115612b1b5782518084602001fd5b8160405162461bcd60e51b81526004016106a591906135ef565b6001600160a01b03811681146106b757600080fd5b600060208284031215612b5c57600080fd5b8135611ea781612b35565b600060208284031215612b7957600080fd5b5035919050565b8035612b8b81612b35565b919050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715612bc957612bc9612b90565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612bf857612bf8612b90565b604052919050565b60008060008060008060c08789031215612c1957600080fd5b8635612c2481612b35565b9550602087810135612c3581612b35565b9550604088013594506060880135612c4c81612b35565b93506080880135925060a088013567ffffffffffffffff80821115612c7057600080fd5b818a0191508a601f830112612c8457600080fd5b813581811115612c9657612c96612b90565b612ca8601f8201601f19168501612bcf565b91508082528b84828501011115612cbe57600080fd5b80848401858401376000848284010152508093505050509295509295509295565b80151581146106b757600080fd5b60008060408385031215612d0057600080fd5b8235612d0b81612b35565b91506020830135612d1b81612cdf565b809150509250929050565b600060208284031215612d3857600080fd5b813560ff81168114611ea757600080fd5b60008060408385031215612d5c57600080fd5b8235612d6781612b35565b91506020830135612d1b81612b35565b600080600060608486031215612d8c57600080fd5b8335612d9781612b35565b92506020840135612da781612b35565b929592945050506040919091013590565b600081518084526020808501945080840160005b83811015612df15781516001600160a01b031687529582019590820190600101612dcc565b509495945050505050565b600081518084526020808501945080840160005b83811015612df157815187529582019590820190600101612e10565b604081526000612e3f6040830185612db8565b8281036020840152612e518185612dfc565b95945050505050565b600067ffffffffffffffff821115612e7457612e74612b90565b5060051b60200190565b600082601f830112612e8f57600080fd5b81356020612ea4612e9f83612e5a565b612bcf565b82815260059290921b84018101918181019086841115612ec357600080fd5b8286015b84811015612ee7578035612eda81612b35565b8352918301918301612ec7565b509695505050505050565b600082601f830112612f0357600080fd5b81356020612f13612e9f83612e5a565b82815260059290921b84018101918181019086841115612f3257600080fd5b8286015b84811015612ee75780358352918301918301612f36565b600060408284031215612f5f57600080fd5b6040516040810181811067ffffffffffffffff82111715612f8257612f82612b90565b6040529050808235612f9381612b35565b815260208301356bffffffffffffffffffffffff81168114612fb457600080fd5b6020919091015292915050565b803563ffffffff81168114612b8b57600080fd5b600060208284031215612fe757600080fd5b813567ffffffffffffffff80821115612fff57600080fd5b9083019060e0828603121561301357600080fd5b61301b612ba6565b82358281111561302a57600080fd5b61303687828601612e7e565b82525060208301358281111561304b57600080fd5b61305787828601612ef2565b60208301525061306960408401612b80565b604082015261307b8660608501612f4d565b606082015261308c60a08401612fc1565b608082015261309d60c08401612b80565b60a082015295945050505050565b60008083601f8401126130bd57600080fd5b50813567ffffffffffffffff8111156130d557600080fd5b6020830191508360208260051b85010111156125fa57600080fd5b6000806020838503121561310357600080fd5b823567ffffffffffffffff81111561311a57600080fd5b613126858286016130ab565b90969095509350505050565b6000806000806080858703121561314857600080fd5b843561315381612b35565b9350602085013561316381612b35565b9250604085013561317381612b35565b9396929550929360600135925050565b6000806000806080858703121561319957600080fd5b84356131a481612b35565b935060208501356131b481612b35565b92506040850135915060608501356131cb81612b35565b939692955090935050565b600080604083850312156131e957600080fd5b82356131f481612b35565b946020939093013593505050565b6000806000806040858703121561321857600080fd5b843567ffffffffffffffff8082111561323057600080fd5b61323c888389016130ab565b9096509450602087013591508082111561325557600080fd5b50613262878288016130ab565b95989497509550505050565b60006020828403121561328057600080fd5b8151611ea781612b35565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b6000602082840312156132e757600080fd5b8151611ea781612cdf565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b60208082526044908201527f53747261746567794d616e616765722e6f6e6c7953747261746567795768697460408201527f656c69737465723a206e6f742074686520737472617465677957686974656c6960608201526339ba32b960e11b608082015260a00190565b602080825260409082018190527f53747261746567794d616e616765722e6f6e6c7944656c65676174696f6e4d61908201527f6e616765723a206e6f74207468652044656c65676174696f6e4d616e61676572606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60e08152600061342b60e0830189612db8565b828103602084015261343d8189612dfc565b6001600160a01b0397881660408501528651881660608501526020909601516bffffffffffffffffffffffff166080840152505063ffffffff9290921660a083015290921660c09092019190915292915050565b6000602082840312156134a357600080fd5b8135611ea781612cdf565b60005b838110156134c95781810151838201526020016134b1565b83811115610c4d5750506000910152565b600081518084526134f28160208601602086016134ae565b601f01601f19169290920160200192915050565b8281526040602082015260006129c360408301846134da565b60006020828403121561353157600080fd5b81516001600160e01b031981168114611ea757600080fd5b60006020828403121561355b57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561358b5761358b613562565b500190565b6000828210156135a2576135a2613562565b500390565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b600082516135e58184602087016134ae565b9190910192915050565b602081526000611ea760208301846134da56fea2646970667358221220af8db90c83e081e833ccb506edfe58292320542a275bdf8901b5381d81c5ab5f64736f6c634300080c0033","storage":{"0x0":"0xff"}},"0xa82ff9afd8f496c3d6ac40e2a0f282e47488cfc9":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122007c3990e071012e67e928be8d71cb1c6b5ed96fee92e98c9e70cc231dee7232064736f6c634300080c0033","storage":{"0x0":"0xe6e340d132b5f46d1e472debcd681b2abc16e57e0001","0x1":"0x0","0x64":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x96":"0x1","0x9c":"0x3","0x9d":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x9e":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x9d4454b023096f34b160d6b654540c56a1f81688","0x683723e34a772b6e4f2c919bba7fa32ed8ea11a8325f54da7db716e9d9dd98c7":"0x643a9800002710","0xaf85b9071dfafeac1409d3f1d19bafc9bc7c37974cde8df0ee6168f0086e539c":"0xf5059a5d33d5853360d16c683c16e67980206f36","0xaf85b9071dfafeac1409d3f1d19bafc9bc7c37974cde8df0ee6168f0086e539d":"0x1613beb3b2c4f22ee086b2b38c1476a3ce7f78e8","0xaf85b9071dfafeac1409d3f1d19bafc9bc7c37974cde8df0ee6168f0086e539e":"0x851356ae760d987e095750cceb3bc6014560891c","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x67d269191c92caf3cd7723f116c85e6e9bf55933"}},"0xb7f8bc63bbcad18155201308c8f3540b07f84f5e":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106103785760003560e01c806360d7faed116101d3578063b7f06ebe11610104578063cf80873e116100a2578063f16172b01161007c578063f16172b01461097d578063f2fde38b14610990578063f698da25146109a3578063fabc1cbc146109ab57600080fd5b8063cf80873e14610936578063da8be86414610957578063eea9064b1461096a57600080fd5b8063c488375a116100de578063c488375a14610853578063c5e480db14610873578063c94b511114610919578063ca661c041461092c57600080fd5b8063b7f06ebe146107f9578063bb45fef21461081c578063c448feb81461084a57600080fd5b8063886f1195116101715780639104c3191161014b5780639104c3191461078457806399be81c81461079f578063a1788484146107b2578063b1344271146107d257600080fd5b8063886f1195146107405780638da5cb5b14610753578063900413471461076457600080fd5b80636d70f7ae116101ad5780636d70f7ae146106e7578063715018a6146106fa578063778e55f3146107025780637f5480711461072d57600080fd5b806360d7faed14610698578063635bbd10146106ab57806365da1264146106be57600080fd5b806329c77d4f116102ad5780634fc40b611161024b5780635ac86ab7116102255780635ac86ab71461062e5780635c975abb146106515780635cfe8d2c146106595780635f966f141461066c57600080fd5b80634fc40b6114610609578063595c6a6714610613578063597b36da1461061b57600080fd5b80633cdeb5e0116102875780633cdeb5e0146105695780633e28391d1461059857806343377382146105bb5780634665bcda146105e257600080fd5b806329c77d4f146104f7578063334043961461051757806339b70e381461052a57600080fd5b8063136439dd1161031a5780631bbce091116102f45780631bbce0911461049757806320606b70146104aa57806322bf40e4146104d157806328a573ae146104e457600080fd5b8063136439dd146104385780631522bf021461044b578063169283651461045e57600080fd5b80630dd8dd02116103565780630dd8dd02146103dd5780630f589e59146103fd57806310d67a2f14610412578063132d49671461042557600080fd5b80630449ca391461037d57806304a4f979146103a35780630b9f487a146103ca575b600080fd5b61039061038b366004614adb565b6109be565b6040519081526020015b60405180910390f35b6103907f14bde674c9f64b2ad00eaaee4a8bed1fabef35c7507e3c5b9cfc9436909a2dad81565b6103906103d8366004614b41565b610a43565b6103f06103eb366004614adb565b610b05565b60405161039a9190614b9c565b61041061040b366004614c39565b610e6e565b005b610410610420366004614c8c565b610fbe565b610410610433366004614cb0565b611071565b610410610446366004614cf1565b611128565b610410610459366004614d0a565b611267565b61039061046c366004614c8c565b6001600160a01b0316600090815260996020526040902060010154600160a01b900463ffffffff1690565b6103906104a5366004614cb0565b61127b565b6103907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6104106104df366004614d75565b6112a9565b6104106104f2366004614cb0565b6113ed565b610390610505366004614c8c565b609b6020526000908152604090205481565b610410610525366004614e1c565b61149d565b6105517f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c981565b6040516001600160a01b03909116815260200161039a565b610551610577366004614c8c565b6001600160a01b039081166000908152609960205260409020600101541690565b6105ab6105a6366004614c8c565b6115da565b604051901515815260200161039a565b6103907f39111bc4a4d688e1f685123d7497d4615370152a8ee4a0593e647bd06ad8bb0b81565b6105517f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85381565b6103906213c68081565b6104106115fa565b61039061062936600461513b565b6116c1565b6105ab61063c366004615177565b606654600160ff9092169190911b9081161490565b606654610390565b6104106106673660046151ed565b6116f1565b61055161067a366004614c8c565b6001600160a01b039081166000908152609960205260409020541690565b6104106106a636600461534d565b61199c565b6104106106b9366004614cf1565b611a37565b6105516106cc366004614c8c565b609a602052600090815260409020546001600160a01b031681565b6105ab6106f5366004614c8c565b611a48565b610410611a68565b6103906107103660046153dc565b609860209081526000928352604080842090915290825290205481565b61041061073b3660046154bd565b611a7c565b606554610551906001600160a01b031681565b6033546001600160a01b0316610551565b61077761077236600461554d565b611b81565b60405161039a91906155d7565b61055173beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac081565b6104106107ad3660046155ea565b611c5b565b6103906107c0366004614c8c565b609f6020526000908152604090205481565b6105517f0000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f81565b6105ab610807366004614cf1565b609e6020526000908152604090205460ff1681565b6105ab61082a36600461561f565b609c60209081526000928352604080842090915290825290205460ff1681565b610390609d5481565b610390610861366004614c8c565b60a16020526000908152604090205481565b6108e3610881366004614c8c565b6040805160608082018352600080835260208084018290529284018190526001600160a01b03948516815260998352839020835191820184528054851682526001015493841691810191909152600160a01b90920463ffffffff169082015290565b6040805182516001600160a01b039081168252602080850151909116908201529181015163ffffffff169082015260600161039a565b61039061092736600461564b565b611d2d565b61039062034bc081565b610949610944366004614c8c565b611de6565b60405161039a9291906156cc565b6103f0610965366004614c8c565b61219e565b6104106109783660046156f1565b612662565b61041061098b366004615749565b61266e565b61041061099e366004614c8c565b6126ff565b610390612775565b6104106109b9366004614cf1565b6127b3565b609d54600090815b83811015610a3b57600060a160008787858181106109e6576109e6615765565b90506020020160208101906109fb9190614c8c565b6001600160a01b03166001600160a01b0316815260200190815260200160002054905082811115610a2a578092505b50610a3481615791565b90506109c6565b509392505050565b604080517f14bde674c9f64b2ad00eaaee4a8bed1fabef35c7507e3c5b9cfc9436909a2dad6020808301919091526001600160a01b038681168385015288811660608401528716608083015260a0820185905260c08083018590528351808403909101815260e0909201909252805191012060009081610ac1612775565b60405161190160f01b602082015260228101919091526042810183905260620160408051808303601f19018152919052805160209091012098975050505050505050565b60665460609060019060029081161415610b3a5760405162461bcd60e51b8152600401610b31906157ac565b60405180910390fd5b6000836001600160401b03811115610b5457610b54614ebe565b604051908082528060200260200182016040528015610b7d578160200160208202803683370190505b50336000908152609a60205260408120549192506001600160a01b03909116905b85811015610e6357868682818110610bb857610bb8615765565b9050602002810190610bca91906157e3565b610bd8906020810190615803565b9050878783818110610bec57610bec615765565b9050602002810190610bfe91906157e3565b610c089080615803565b905014610c7d5760405162461bcd60e51b815260206004820152603860248201527f44656c65676174696f6e4d616e616765722e717565756557697468647261776160448201527f6c3a20696e707574206c656e677468206d69736d6174636800000000000000006064820152608401610b31565b33878783818110610c9057610c90615765565b9050602002810190610ca291906157e3565b610cb3906060810190604001614c8c565b6001600160a01b031614610d2f5760405162461bcd60e51b815260206004820152603c60248201527f44656c65676174696f6e4d616e616765722e717565756557697468647261776160448201527f6c3a2077697468647261776572206d757374206265207374616b6572000000006064820152608401610b31565b610e343383898985818110610d4657610d46615765565b9050602002810190610d5891906157e3565b610d69906060810190604001614c8c565b8a8a86818110610d7b57610d7b615765565b9050602002810190610d8d91906157e3565b610d979080615803565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508e92508d9150889050818110610ddd57610ddd615765565b9050602002810190610def91906157e3565b610dfd906020810190615803565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061290f92505050565b838281518110610e4657610e46615765565b602090810291909101015280610e5b81615791565b915050610b9e565b509095945050505050565b336000908152609960205260409020546001600160a01b031615610f085760405162461bcd60e51b815260206004820152604560248201527f44656c65676174696f6e4d616e616765722e726567697374657241734f70657260448201527f61746f723a206f70657261746f722068617320616c72656164792072656769736064820152641d195c995960da1b608482015260a401610b31565b610f123384612ecf565b604080518082019091526060815260006020820152610f34338083600061316b565b336001600160a01b03167f8e8485583a2310d41f7c82b9427d0bd49bad74bb9cff9d3402a29d8f9b28a0e285604051610f6d919061584c565b60405180910390a2336001600160a01b03167f02a919ed0e2acad1dd90f17ef2fa4ae5462ee1339170034a8531cca4b67080908484604051610fb092919061589e565b60405180910390a250505050565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611011573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103591906158cd565b6001600160a01b0316336001600160a01b0316146110655760405162461bcd60e51b8152600401610b31906158ea565b61106e81613510565b50565b336001600160a01b037f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c91614806110d05750336001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85316145b6110ec5760405162461bcd60e51b8152600401610b3190615934565b6110f5836115da565b15611123576001600160a01b038084166000908152609a60205260409020541661112181858585613607565b505b505050565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015611170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111949190615991565b6111b05760405162461bcd60e51b8152600401610b31906159ae565b606654818116146112295760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610b31565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b61126f613682565b611121848484846136dc565b6001600160a01b0383166000908152609b60205260408120546112a085828686611d2d565b95945050505050565b600054610100900460ff16158080156112c95750600054600160ff909116105b806112e35750303b1580156112e3575060005460ff166001145b6113465760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610b31565b6000805460ff191660011790558015611369576000805461ff0019166101001790555b6113738888613902565b61137b6139e8565b60975561138789613a7f565b61139086613ad1565b61139c858585856136dc565b80156113e2576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050505050565b336001600160a01b037f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c916148061144c5750336001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85316145b6114685760405162461bcd60e51b8152600401610b3190615934565b611471836115da565b15611123576001600160a01b038084166000908152609a60205260409020541661112181858585613bcb565b606654600290600490811614156114c65760405162461bcd60e51b8152600401610b31906157ac565b600260c95414156115195760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b31565b600260c95560005b888110156115c9576115b98a8a8381811061153e5761153e615765565b905060200281019061155091906159f6565b89898481811061156257611562615765565b90506020028101906115749190615803565b89898681811061158657611586615765565b9050602002013588888781811061159f5761159f615765565b90506020020160208101906115b49190615a0c565b613c46565b6115c281615791565b9050611521565b5050600160c9555050505050505050565b6001600160a01b039081166000908152609a602052604090205416151590565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015611642573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116669190615991565b6116825760405162461bcd60e51b8152600401610b31906159ae565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b6000816040516020016116d49190615a9d565b604051602081830303815290604052805190602001209050919050565b60005b815181101561199857600082828151811061171157611711615765565b602002602001015190506000807f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c96001600160a01b031663cd293f6f846040518263ffffffff1660e01b815260040161176a9190615ab0565b60408051808303816000875af1158015611788573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ac9190615b5c565b91509150811561198a576040808401516001600160a01b0381166000908152609f602052918220805491928291906117e383615791565b919050555060006040518060e00160405280846001600160a01b031681526020018760a001516001600160a01b031681526020018760600151600001516001600160a01b03168152602001838152602001876080015163ffffffff16815260200187600001518152602001876020015181525090506000611863826116c1565b6000818152609e602052604090205490915060ff16156118f95760405162461bcd60e51b815260206004820152604560248201527f44656c65676174696f6e4d616e616765722e6d6967726174655175657565645760448201527f69746864726177616c733a207769746864726177616c20616c72656164792065606482015264786973747360d81b608482015260a401610b31565b6000818152609e602052604090819020805460ff19166001179055517f9009ab153e8014fbfb02f2217f5cde7aa7f9ad734ae85ca3ee3f4ca2fdd499f9906119449083908590615b8a565b60405180910390a160408051868152602081018390527fdc00758b65eef71dc3780c04ebe36cab6bdb266c3a698187e29e0f0dca012630910160405180910390a1505050505b8360010193505050506116f4565b5050565b606654600290600490811614156119c55760405162461bcd60e51b8152600401610b31906157ac565b600260c9541415611a185760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b31565b600260c955611a2a8686868686613c46565b5050600160c95550505050565b611a3f613682565b61106e81613ad1565b6001600160a01b0390811660009081526099602052604090205416151590565b611a70613682565b611a7a6000613a7f565b565b4283602001511015611b005760405162461bcd60e51b815260206004820152604160248201527f44656c65676174696f6e4d616e616765722e64656c6567617465546f4279536960448201527f676e61747572653a207374616b6572207369676e6174757265206578706972656064820152601960fa1b608482015260a401610b31565b6000609b6000876001600160a01b03166001600160a01b031681526020019081526020016000205490506000611b3c8783888860200151611d2d565b6001600160a01b0388166000908152609b602052604090206001840190558551909150611b6c9088908390614430565b611b788787868661316b565b50505050505050565b6060600082516001600160401b03811115611b9e57611b9e614ebe565b604051908082528060200260200182016040528015611bc7578160200160208202803683370190505b50905060005b8351811015610a3b576001600160a01b03851660009081526098602052604081208551909190869084908110611c0557611c05615765565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054828281518110611c4057611c40615765565b6020908102919091010152611c5481615791565b9050611bcd565b611c6433611a48565b611ce65760405162461bcd60e51b815260206004820152604760248201527f44656c65676174696f6e4d616e616765722e7570646174654f70657261746f7260448201527f4d657461646174615552493a2063616c6c6572206d75737420626520616e206f6064820152663832b930ba37b960c91b608482015260a401610b31565b336001600160a01b03167f02a919ed0e2acad1dd90f17ef2fa4ae5462ee1339170034a8531cca4b67080908383604051611d2192919061589e565b60405180910390a25050565b604080517f39111bc4a4d688e1f685123d7497d4615370152a8ee4a0593e647bd06ad8bb0b6020808301919091526001600160a01b0387811683850152851660608301526080820186905260a08083018590528351808403909101815260c0909201909252805191012060009081611da3612775565b60405161190160f01b602082015260228101919091526042810183905260620160408051808303601f190181529190528051602090910120979650505050505050565b6040516360f4062b60e01b81526001600160a01b03828116600483015260609182916000917f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c853909116906360f4062b90602401602060405180830381865afa158015611e56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7a9190615ba3565b6040516394f649dd60e01b81526001600160a01b03868116600483015291925060009182917f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c9909116906394f649dd90602401600060405180830381865afa158015611eea573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f129190810190615c17565b9150915060008313611f2957909590945092505050565b606080835160001415611fe3576040805160018082528183019092529060208083019080368337505060408051600180825281830190925292945090506020808301908036833701905050905073beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac082600081518110611f9e57611f9e615765565b60200260200101906001600160a01b031690816001600160a01b0316815250508481600081518110611fd257611fd2615765565b602002602001018181525050612191565b8351611ff0906001615cd1565b6001600160401b0381111561200757612007614ebe565b604051908082528060200260200182016040528015612030578160200160208202803683370190505b50915081516001600160401b0381111561204c5761204c614ebe565b604051908082528060200260200182016040528015612075578160200160208202803683370190505b50905060005b845181101561210f5784818151811061209657612096615765565b60200260200101518382815181106120b0576120b0615765565b60200260200101906001600160a01b031690816001600160a01b0316815250508381815181106120e2576120e2615765565b60200260200101518282815181106120fc576120fc615765565b602090810291909101015260010161207b565b5073beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac082600184516121349190615ce9565b8151811061214457612144615765565b60200260200101906001600160a01b031690816001600160a01b0316815250508481600184516121749190615ce9565b8151811061218457612184615765565b6020026020010181815250505b9097909650945050505050565b606654606090600190600290811614156121ca5760405162461bcd60e51b8152600401610b31906157ac565b6121d3836115da565b6122535760405162461bcd60e51b8152602060048201526044602482018190527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a207374908201527f616b6572206d7573742062652064656c65676174656420746f20756e64656c656064820152636761746560e01b608482015260a401610b31565b61225c83611a48565b156122cf5760405162461bcd60e51b815260206004820152603d60248201527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a206f7060448201527f657261746f72732063616e6e6f7420626520756e64656c6567617465640000006064820152608401610b31565b6001600160a01b03831661234b5760405162461bcd60e51b815260206004820152603c60248201527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a20636160448201527f6e6e6f7420756e64656c6567617465207a65726f2061646472657373000000006064820152608401610b31565b6001600160a01b038084166000818152609a60205260409020549091169033148061237e5750336001600160a01b038216145b806123a557506001600160a01b038181166000908152609960205260409020600101541633145b6124175760405162461bcd60e51b815260206004820152603d60248201527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a20636160448201527f6c6c65722063616e6e6f7420756e64656c6567617465207374616b65720000006064820152608401610b31565b60008061242386611de6565b9092509050336001600160a01b0387161461247957826001600160a01b0316866001600160a01b03167ff0eddf07e6ea14f388b47e1e94a0f464ecbd9eed4171130e0fc0e99fb4030a8a60405160405180910390a35b826001600160a01b0316866001600160a01b03167ffee30966a256b71e14bc0ebfc94315e28ef4a97a7131a9e2b7a310a73af4467660405160405180910390a36001600160a01b0386166000908152609a6020526040902080546001600160a01b031916905581516124fb576040805160008152602081019091529450612659565b81516001600160401b0381111561251457612514614ebe565b60405190808252806020026020018201604052801561253d578160200160208202803683370190505b50945060005b8251811015612657576040805160018082528183019092526000916020808301908036833750506040805160018082528183019092529293506000929150602080830190803683370190505090508483815181106125a3576125a3615765565b6020026020010151826000815181106125be576125be615765565b60200260200101906001600160a01b031690816001600160a01b0316815250508383815181106125f0576125f0615765565b60200260200101518160008151811061260b5761260b615765565b60200260200101818152505061262489878b858561290f565b88848151811061263657612636615765565b6020026020010181815250505050808061264f90615791565b915050612543565b505b50505050919050565b6111233384848461316b565b61267733611a48565b6126f55760405162461bcd60e51b815260206004820152604360248201527f44656c65676174696f6e4d616e616765722e6d6f646966794f70657261746f7260448201527f44657461696c733a2063616c6c6572206d75737420626520616e206f706572616064820152623a37b960e91b608482015260a401610b31565b61106e3382612ecf565b612707613682565b6001600160a01b03811661276c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b31565b61106e81613a7f565b60007f0000000000000000000000000000000000000000000000000000000000007a694614156127a6575060975490565b6127ae6139e8565b905090565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612806573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061282a91906158cd565b6001600160a01b0316336001600160a01b03161461285a5760405162461bcd60e51b8152600401610b31906158ea565b6066541981196066541916146128d85760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610b31565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c9060200161125c565b60006001600160a01b0386166129a65760405162461bcd60e51b815260206004820152605060248201527f44656c65676174696f6e4d616e616765722e5f72656d6f76655368617265734160448201527f6e6451756575655769746864726177616c3a207374616b65722063616e6e6f7460648201526f206265207a65726f206164647265737360801b608482015260a401610b31565b8251612a305760405162461bcd60e51b815260206004820152604d60248201527f44656c65676174696f6e4d616e616765722e5f72656d6f76655368617265734160448201527f6e6451756575655769746864726177616c3a207374726174656769657320636160648201526c6e6e6f7420626520656d70747960981b608482015260a401610b31565b60005b8351811015612ddd576001600160a01b03861615612a8957612a898688868481518110612a6257612a62615765565b6020026020010151868581518110612a7c57612a7c615765565b6020026020010151613607565b73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06001600160a01b0316848281518110612ab957612ab9615765565b60200260200101516001600160a01b03161415612b82577f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031663beffbb8988858481518110612b1257612b12615765565b60200260200101516040518363ffffffff1660e01b8152600401612b4b9291906001600160a01b03929092168252602082015260400190565b600060405180830381600087803b158015612b6557600080fd5b505af1158015612b79573d6000803e3d6000fd5b50505050612dd5565b846001600160a01b0316876001600160a01b03161480612c5457507f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c96001600160a01b0316639b4da03d858381518110612bde57612bde615765565b60200260200101516040518263ffffffff1660e01b8152600401612c1191906001600160a01b0391909116815260200190565b602060405180830381865afa158015612c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c529190615991565b155b612d205760405162461bcd60e51b8152602060048201526084602482018190527f44656c65676174696f6e4d616e616765722e5f72656d6f76655368617265734160448301527f6e6451756575655769746864726177616c3a2077697468647261776572206d7560648301527f73742062652073616d652061646472657373206173207374616b657220696620908201527f746869726450617274795472616e7366657273466f7262696464656e2061726560a482015263081cd95d60e21b60c482015260e401610b31565b7f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c96001600160a01b0316638c80d4e588868481518110612d6257612d62615765565b6020026020010151868581518110612d7c57612d7c615765565b60200260200101516040518463ffffffff1660e01b8152600401612da293929190615d00565b600060405180830381600087803b158015612dbc57600080fd5b505af1158015612dd0573d6000803e3d6000fd5b505050505b600101612a33565b506001600160a01b0386166000908152609f60205260408120805491829190612e0583615791565b919050555060006040518060e00160405280896001600160a01b03168152602001886001600160a01b03168152602001876001600160a01b031681526020018381526020014363ffffffff1681526020018681526020018581525090506000612e6d826116c1565b6000818152609e602052604090819020805460ff19166001179055519091507f9009ab153e8014fbfb02f2217f5cde7aa7f9ad734ae85ca3ee3f4ca2fdd499f990612ebb9083908590615b8a565b60405180910390a198975050505050505050565b6000612ede6020830183614c8c565b6001600160a01b03161415612f785760405162461bcd60e51b815260206004820152605460248201527f44656c65676174696f6e4d616e616765722e5f7365744f70657261746f72446560448201527f7461696c733a2063616e6e6f742073657420606561726e696e677352656365696064820152737665726020746f207a65726f206164647265737360601b608482015260a401610b31565b6213c680612f8c6060830160408401615d24565b63ffffffff1611156130415760405162461bcd60e51b815260206004820152606c60248201527f44656c65676174696f6e4d616e616765722e5f7365744f70657261746f72446560448201527f7461696c733a207374616b65724f70744f757457696e646f77426c6f636b732060648201527f63616e6e6f74206265203e204d41585f5354414b45525f4f50545f4f55545f5760848201526b494e444f575f424c4f434b5360a01b60a482015260c401610b31565b6001600160a01b0382166000908152609960205260409081902060010154600160a01b900463ffffffff169061307d9060608401908401615d24565b63ffffffff1610156131135760405162461bcd60e51b815260206004820152605360248201527f44656c65676174696f6e4d616e616765722e5f7365744f70657261746f72446560448201527f7461696c733a207374616b65724f70744f757457696e646f77426c6f636b732060648201527218d85b9b9bdd08189948191958dc99585cd959606a1b608482015260a401610b31565b6001600160a01b038216600090815260996020526040902081906131378282615d61565b505060405133907ffebe5cd24b2cbc7b065b9d0fdeb904461e4afcff57dd57acda1e7832031ba7ac90611d2190849061584c565b606654600090600190811614156131945760405162461bcd60e51b8152600401610b31906157ac565b61319d856115da565b1561321a5760405162461bcd60e51b815260206004820152604160248201527f44656c65676174696f6e4d616e616765722e5f64656c65676174653a2073746160448201527f6b657220697320616c7265616479206163746976656c792064656c65676174656064820152601960fa1b608482015260a401610b31565b61322384611a48565b6132a35760405162461bcd60e51b815260206004820152604560248201527f44656c65676174696f6e4d616e616765722e5f64656c65676174653a206f706560448201527f7261746f72206973206e6f74207265676973746572656420696e20456967656e6064820152642630bcb2b960d91b608482015260a401610b31565b6001600160a01b038085166000908152609960205260409020600101541680158015906132d95750336001600160a01b03821614155b80156132ee5750336001600160a01b03861614155b1561345b57428460200151101561336d5760405162461bcd60e51b815260206004820152603760248201527f44656c65676174696f6e4d616e616765722e5f64656c65676174653a2061707060448201527f726f766572207369676e617475726520657870697265640000000000000000006064820152608401610b31565b6001600160a01b0381166000908152609c6020908152604080832086845290915290205460ff16156134075760405162461bcd60e51b815260206004820152603760248201527f44656c65676174696f6e4d616e616765722e5f64656c65676174653a2061707060448201527f726f76657253616c7420616c7265616479207370656e740000000000000000006064820152608401610b31565b6001600160a01b0381166000908152609c6020908152604080832086845282528220805460ff19166001179055850151613448908890889085908890610a43565b905061345982828760000151614430565b505b6001600160a01b038681166000818152609a602052604080822080546001600160a01b031916948a169485179055517fc3ee9f2e5fda98e8066a1f745b2df9285f416fe98cf2559cd21484b3d87433049190a36000806134ba88611de6565b9150915060005b82518110156113e257613508888a8584815181106134e1576134e1615765565b60200260200101518585815181106134fb576134fb615765565b6020026020010151613bcb565b6001016134c1565b6001600160a01b03811661359e5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610b31565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0380851660009081526098602090815260408083209386168352929052908120805483929061363e908490615ce9565b92505081905550836001600160a01b03167f6909600037b75d7b4733aedd815442b5ec018a827751c832aaff64eba5d6d2dd848484604051610fb093929190615d00565b6033546001600160a01b03163314611a7a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b31565b8281146137645760405162461bcd60e51b815260206004820152604a60248201527f44656c65676174696f6e4d616e616765722e5f7365745374726174656779576960448201527f746864726177616c44656c6179426c6f636b733a20696e707574206c656e67746064820152690d040dad2e6dac2e8c6d60b31b608482015260a401610b31565b8260005b818110156138fa57600086868381811061378457613784615765565b90506020020160208101906137999190614c8c565b6001600160a01b038116600090815260a160205260408120549192508686858181106137c7576137c7615765565b90506020020135905062034bc081111561388b5760405162461bcd60e51b815260206004820152607360248201527f44656c65676174696f6e4d616e616765722e5f7365745374726174656779576960448201527f746864726177616c44656c6179426c6f636b733a205f7769746864726177616c60648201527f44656c6179426c6f636b732063616e6e6f74206265203e204d41585f5749544860848201527244524157414c5f44454c41595f424c4f434b5360681b60a482015260c401610b31565b6001600160a01b038316600081815260a160209081526040918290208490558151928352820184905281018290527f0e7efa738e8b0ce6376a0c1af471655540d2e9a81647d7b09ed823018426576d9060600160405180910390a1505050806138f390615791565b9050613768565b505050505050565b6065546001600160a01b031615801561392357506001600160a01b03821615155b6139a55760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610b31565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a261199882613510565b604080518082018252600a81526922b4b3b2b72630bcb2b960b11b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f71b625cfad44bac63b13dba07f2e1d6084ee04b6f8752101ece6126d584ee6ea81840152466060820152306080808301919091528351808303909101815260a0909101909252815191012090565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b62034bc0811115613b8a5760405162461bcd60e51b815260206004820152607160248201527f44656c65676174696f6e4d616e616765722e5f7365744d696e5769746864726160448201527f77616c44656c6179426c6f636b733a205f6d696e5769746864726177616c446560648201527f6c6179426c6f636b732063616e6e6f74206265203e204d41585f5749544844526084820152704157414c5f44454c41595f424c4f434b5360781b60a482015260c401610b31565b609d5460408051918252602082018390527fafa003cd76f87ff9d62b35beea889920f33c0c42b8d45b74954d61d50f4b6b69910160405180910390a1609d55565b6001600160a01b03808516600090815260986020908152604080832093861683529290529081208054839290613c02908490615cd1565b92505081905550836001600160a01b03167f1ec042c965e2edd7107b51188ee0f383e22e76179041ab3a9d18ff151405166c848484604051610fb093929190615d00565b6000613c5461062987615dc4565b6000818152609e602052604090205490915060ff16613cd55760405162461bcd60e51b81526020600482015260436024820152600080516020615efc83398151915260448201527f645769746864726177616c3a20616374696f6e206973206e6f7420696e20717560648201526265756560e81b608482015260a401610b31565b609d544390613cea60a0890160808a01615d24565b63ffffffff16613cfa9190615cd1565b1115613d825760405162461bcd60e51b815260206004820152605f6024820152600080516020615efc83398151915260448201527f645769746864726177616c3a206d696e5769746864726177616c44656c61794260648201527f6c6f636b7320706572696f6420686173206e6f74207965742070617373656400608482015260a401610b31565b613d926060870160408801614c8c565b6001600160a01b0316336001600160a01b031614613e1f5760405162461bcd60e51b81526020600482015260506024820152600080516020615efc83398151915260448201527f645769746864726177616c3a206f6e6c7920776974686472617765722063616e60648201526f1031b7b6b83632ba329030b1ba34b7b760811b608482015260a401610b31565b8115613ea157613e3260a0870187615803565b85149050613ea15760405162461bcd60e51b81526020600482015260426024820152600080516020615efc83398151915260448201527f645769746864726177616c3a20696e707574206c656e677468206d69736d61746064820152610c6d60f31b608482015260a401610b31565b6000818152609e60205260409020805460ff1916905581156140065760005b613ecd60a0880188615803565b9050811015614000574360a16000613ee860a08b018b615803565b85818110613ef857613ef8615765565b9050602002016020810190613f0d9190614c8c565b6001600160a01b03168152602081019190915260400160002054613f3760a08a0160808b01615d24565b63ffffffff16613f479190615cd1565b1115613f655760405162461bcd60e51b8152600401610b3190615dd6565b613ff8613f756020890189614c8c565b33613f8360a08b018b615803565b85818110613f9357613f93615765565b9050602002016020810190613fa89190614c8c565b613fb560c08c018c615803565b86818110613fc557613fc5615765565b905060200201358a8a87818110613fde57613fde615765565b9050602002016020810190613ff39190614c8c565b6145ea565b600101613ec0565b506143f5565b336000908152609a60205260408120546001600160a01b0316905b61402e60a0890189615803565b90508110156143f2574360a1600061404960a08c018c615803565b8581811061405957614059615765565b905060200201602081019061406e9190614c8c565b6001600160a01b0316815260208101919091526040016000205461409860a08b0160808c01615d24565b63ffffffff166140a89190615cd1565b11156140c65760405162461bcd60e51b8152600401610b3190615dd6565b73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06140e860a08a018a615803565b838181106140f8576140f8615765565b905060200201602081019061410d9190614c8c565b6001600160a01b0316141561425d57600061412b60208a018a614c8c565b905060006001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85316630e81073c8361416c60c08e018e615803565b8781811061417c5761417c615765565b6040516001600160e01b031960e087901b1681526001600160a01b03909416600485015260200291909101356024830152506044016020604051808303816000875af11580156141d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141f49190615ba3565b6001600160a01b038084166000908152609a602052604090205491925016801561425557614255818461422a60a08f018f615803565b8881811061423a5761423a615765565b905060200201602081019061424f9190614c8c565b85613bcb565b5050506143ea565b7f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c96001600160a01b031663c4623ea13389898581811061429f5761429f615765565b90506020020160208101906142b49190614c8c565b6142c160a08d018d615803565b868181106142d1576142d1615765565b90506020020160208101906142e69190614c8c565b6142f360c08e018e615803565b8781811061430357614303615765565b60405160e088901b6001600160e01b03191681526001600160a01b03968716600482015294861660248601529290941660448401526020909102013560648201526084019050600060405180830381600087803b15801561436357600080fd5b505af1158015614377573d6000803e3d6000fd5b505050506001600160a01b038216156143ea576143ea823361439c60a08c018c615803565b858181106143ac576143ac615765565b90506020020160208101906143c19190614c8c565b6143ce60c08d018d615803565b868181106143de576143de615765565b90506020020135613bcb565b600101614021565b50505b6040518181527fc97098c2f658800b4df29001527f7324bcdffcf6e8751a699ab920a1eced5b1d9060200160405180910390a1505050505050565b6001600160a01b0383163b1561454a57604051630b135d3f60e11b808252906001600160a01b03851690631626ba7e906144709086908690600401615e5e565b602060405180830381865afa15801561448d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144b19190615ebb565b6001600160e01b031916146111235760405162461bcd60e51b815260206004820152605360248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a2045524331323731207369676e6174757265206064820152721d995c9a599a58d85d1a5bdb8819985a5b1959606a1b608482015260a401610b31565b826001600160a01b031661455e838361472a565b6001600160a01b0316146111235760405162461bcd60e51b815260206004820152604760248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a207369676e6174757265206e6f742066726f6d6064820152661039b4b3b732b960c91b608482015260a401610b31565b6001600160a01b03831673beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac014156146955760405162387b1360e81b81526001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c853169063387b13009061465e90889088908790600401615d00565b600060405180830381600087803b15801561467857600080fd5b505af115801561468c573d6000803e3d6000fd5b50505050614723565b60405163c608c7f360e01b81526001600160a01b03858116600483015284811660248301526044820184905282811660648301527f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c9169063c608c7f390608401600060405180830381600087803b15801561470f57600080fd5b505af11580156113e2573d6000803e3d6000fd5b5050505050565b60008060006147398585614746565b91509150610a3b816147b6565b60008082516041141561477d5760208301516040840151606085015160001a61477187828585614971565b945094505050506147af565b8251604014156147a7576020830151604084015161479c868383614a5e565b9350935050506147af565b506000905060025b9250929050565b60008160048111156147ca576147ca615ee5565b14156147d35750565b60018160048111156147e7576147e7615ee5565b14156148355760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610b31565b600281600481111561484957614849615ee5565b14156148975760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610b31565b60038160048111156148ab576148ab615ee5565b14156149045760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610b31565b600481600481111561491857614918615ee5565b141561106e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610b31565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156149a85750600090506003614a55565b8460ff16601b141580156149c057508460ff16601c14155b156149d15750600090506004614a55565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614a25573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116614a4e57600060019250925050614a55565b9150600090505b94509492505050565b6000806001600160ff1b03831681614a7b60ff86901c601b615cd1565b9050614a8987828885614971565b935093505050935093915050565b60008083601f840112614aa957600080fd5b5081356001600160401b03811115614ac057600080fd5b6020830191508360208260051b85010111156147af57600080fd5b60008060208385031215614aee57600080fd5b82356001600160401b03811115614b0457600080fd5b614b1085828601614a97565b90969095509350505050565b6001600160a01b038116811461106e57600080fd5b8035614b3c81614b1c565b919050565b600080600080600060a08688031215614b5957600080fd5b8535614b6481614b1c565b94506020860135614b7481614b1c565b93506040860135614b8481614b1c565b94979396509394606081013594506080013592915050565b6020808252825182820181905260009190848201906040850190845b81811015614bd457835183529284019291840191600101614bb8565b50909695505050505050565b600060608284031215614bf257600080fd5b50919050565b60008083601f840112614c0a57600080fd5b5081356001600160401b03811115614c2157600080fd5b6020830191508360208285010111156147af57600080fd5b600080600060808486031215614c4e57600080fd5b614c588585614be0565b925060608401356001600160401b03811115614c7357600080fd5b614c7f86828701614bf8565b9497909650939450505050565b600060208284031215614c9e57600080fd5b8135614ca981614b1c565b9392505050565b600080600060608486031215614cc557600080fd5b8335614cd081614b1c565b92506020840135614ce081614b1c565b929592945050506040919091013590565b600060208284031215614d0357600080fd5b5035919050565b60008060008060408587031215614d2057600080fd5b84356001600160401b0380821115614d3757600080fd5b614d4388838901614a97565b90965094506020870135915080821115614d5c57600080fd5b50614d6987828801614a97565b95989497509550505050565b60008060008060008060008060c0898b031215614d9157600080fd5b8835614d9c81614b1c565b97506020890135614dac81614b1c565b9650604089013595506060890135945060808901356001600160401b0380821115614dd657600080fd5b614de28c838d01614a97565b909650945060a08b0135915080821115614dfb57600080fd5b50614e088b828c01614a97565b999c989b5096995094979396929594505050565b6000806000806000806000806080898b031215614e3857600080fd5b88356001600160401b0380821115614e4f57600080fd5b614e5b8c838d01614a97565b909a50985060208b0135915080821115614e7457600080fd5b614e808c838d01614a97565b909850965060408b0135915080821115614e9957600080fd5b614ea58c838d01614a97565b909650945060608b0135915080821115614dfb57600080fd5b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b0381118282101715614ef657614ef6614ebe565b60405290565b604080519081016001600160401b0381118282101715614ef657614ef6614ebe565b60405160c081016001600160401b0381118282101715614ef657614ef6614ebe565b604051601f8201601f191681016001600160401b0381118282101715614f6857614f68614ebe565b604052919050565b63ffffffff8116811461106e57600080fd5b8035614b3c81614f70565b60006001600160401b03821115614fa657614fa6614ebe565b5060051b60200190565b600082601f830112614fc157600080fd5b81356020614fd6614fd183614f8d565b614f40565b82815260059290921b84018101918181019086841115614ff557600080fd5b8286015b8481101561501957803561500c81614b1c565b8352918301918301614ff9565b509695505050505050565b600082601f83011261503557600080fd5b81356020615045614fd183614f8d565b82815260059290921b8401810191818101908684111561506457600080fd5b8286015b848110156150195780358352918301918301615068565b600060e0828403121561509157600080fd5b615099614ed4565b90506150a482614b31565b81526150b260208301614b31565b60208201526150c360408301614b31565b6040820152606082013560608201526150de60808301614f82565b608082015260a08201356001600160401b03808211156150fd57600080fd5b61510985838601614fb0565b60a084015260c084013591508082111561512257600080fd5b5061512f84828501615024565b60c08301525092915050565b60006020828403121561514d57600080fd5b81356001600160401b0381111561516357600080fd5b61516f8482850161507f565b949350505050565b60006020828403121561518957600080fd5b813560ff81168114614ca957600080fd5b6000604082840312156151ac57600080fd5b6151b4614efc565b905081356151c181614b1c565b815260208201356bffffffffffffffffffffffff811681146151e257600080fd5b602082015292915050565b6000602080838503121561520057600080fd5b82356001600160401b038082111561521757600080fd5b818501915085601f83011261522b57600080fd5b8135615239614fd182614f8d565b81815260059190911b8301840190848101908883111561525857600080fd5b8585015b83811015615332578035858111156152745760008081fd5b860160e0818c03601f190181131561528c5760008081fd5b615294614f1e565b89830135888111156152a65760008081fd5b6152b48e8c83870101614fb0565b825250604080840135898111156152cb5760008081fd5b6152d98f8d83880101615024565b8c8401525060606152eb818601614b31565b82840152608091506152ff8f83870161519a565b9083015261530f60c08501614f82565b9082015261531e838301614b31565b60a08201528552505091860191860161525c565b5098975050505050505050565b801515811461106e57600080fd5b60008060008060006080868803121561536557600080fd5b85356001600160401b038082111561537c57600080fd5b9087019060e0828a03121561539057600080fd5b909550602087013590808211156153a657600080fd5b506153b388828901614a97565b9095509350506040860135915060608601356153ce8161533f565b809150509295509295909350565b600080604083850312156153ef57600080fd5b82356153fa81614b1c565b9150602083013561540a81614b1c565b809150509250929050565b60006040828403121561542757600080fd5b61542f614efc565b905081356001600160401b038082111561544857600080fd5b818401915084601f83011261545c57600080fd5b813560208282111561547057615470614ebe565b615482601f8301601f19168201614f40565b9250818352868183860101111561549857600080fd5b8181850182850137600081838501015282855280860135818601525050505092915050565b600080600080600060a086880312156154d557600080fd5b85356154e081614b1c565b945060208601356154f081614b1c565b935060408601356001600160401b038082111561550c57600080fd5b61551889838a01615415565b9450606088013591508082111561552e57600080fd5b5061553b88828901615415565b95989497509295608001359392505050565b6000806040838503121561556057600080fd5b823561556b81614b1c565b915060208301356001600160401b0381111561558657600080fd5b61559285828601614fb0565b9150509250929050565b600081518084526020808501945080840160005b838110156155cc578151875295820195908201906001016155b0565b509495945050505050565b602081526000614ca9602083018461559c565b600080602083850312156155fd57600080fd5b82356001600160401b0381111561561357600080fd5b614b1085828601614bf8565b6000806040838503121561563257600080fd5b823561563d81614b1c565b946020939093013593505050565b6000806000806080858703121561566157600080fd5b843561566c81614b1c565b935060208501359250604085013561568381614b1c565b9396929550929360600135925050565b600081518084526020808501945080840160005b838110156155cc5781516001600160a01b0316875295820195908201906001016156a7565b6040815260006156df6040830185615693565b82810360208401526112a0818561559c565b60008060006060848603121561570657600080fd5b833561571181614b1c565b925060208401356001600160401b0381111561572c57600080fd5b61573886828701615415565b925050604084013590509250925092565b60006060828403121561575b57600080fd5b614ca98383614be0565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156157a5576157a561577b565b5060010190565b60208082526019908201527f5061757361626c653a20696e6465782069732070617573656400000000000000604082015260600190565b60008235605e198336030181126157f957600080fd5b9190910192915050565b6000808335601e1984360301811261581a57600080fd5b8301803591506001600160401b0382111561583457600080fd5b6020019150600581901b36038213156147af57600080fd5b60608101823561585b81614b1c565b6001600160a01b03908116835260208401359061587782614b1c565b166020830152604083013561588b81614f70565b63ffffffff811660408401525092915050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6000602082840312156158df57600080fd5b8151614ca981614b1c565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b60208082526037908201527f44656c65676174696f6e4d616e616765723a206f6e6c7953747261746567794d60408201527f616e616765724f72456967656e506f644d616e61676572000000000000000000606082015260800190565b6000602082840312156159a357600080fd5b8151614ca98161533f565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b6000823560de198336030181126157f957600080fd5b600060208284031215615a1e57600080fd5b8135614ca98161533f565b600060018060a01b03808351168452806020840151166020850152806040840151166040850152506060820151606084015263ffffffff608083015116608084015260a082015160e060a0850152615a8460e0850182615693565b905060c083015184820360c08601526112a0828261559c565b602081526000614ca96020830184615a29565b602081526000825160e06020840152615acd610100840182615693565b90506020840151601f19848303016040850152615aea828261559c565b915050604084015160018060a01b03808216606086015260608601519150808251166080860152506bffffffffffffffffffffffff60208201511660a0850152506080840151615b4260c085018263ffffffff169052565b5060a08401516001600160a01b03811660e0850152610a3b565b60008060408385031215615b6f57600080fd5b8251615b7a8161533f565b6020939093015192949293505050565b82815260406020820152600061516f6040830184615a29565b600060208284031215615bb557600080fd5b5051919050565b600082601f830112615bcd57600080fd5b81516020615bdd614fd183614f8d565b82815260059290921b84018101918181019086841115615bfc57600080fd5b8286015b848110156150195780518352918301918301615c00565b60008060408385031215615c2a57600080fd5b82516001600160401b0380821115615c4157600080fd5b818501915085601f830112615c5557600080fd5b81516020615c65614fd183614f8d565b82815260059290921b84018101918181019089841115615c8457600080fd5b948201945b83861015615cab578551615c9c81614b1c565b82529482019490820190615c89565b91880151919650909350505080821115615cc457600080fd5b5061559285828601615bbc565b60008219821115615ce457615ce461577b565b500190565b600082821015615cfb57615cfb61577b565b500390565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600060208284031215615d3657600080fd5b8135614ca981614f70565b80546001600160a01b0319166001600160a01b0392909216919091179055565b8135615d6c81614b1c565b615d768183615d41565b50600181016020830135615d8981614b1c565b615d938183615d41565b506040830135615da281614f70565b815463ffffffff60a01b191660a09190911b63ffffffff60a01b161790555050565b6000615dd0368361507f565b92915050565b6020808252606e90820152600080516020615efc83398151915260408201527f645769746864726177616c3a207769746864726177616c44656c6179426c6f6360608201527f6b7320706572696f6420686173206e6f74207965742070617373656420666f7260808201526d207468697320737472617465677960901b60a082015260c00190565b82815260006020604081840152835180604085015260005b81811015615e9257858101830151858201606001528201615e76565b81811115615ea4576000606083870101525b50601f01601f191692909201606001949350505050565b600060208284031215615ecd57600080fd5b81516001600160e01b031981168114614ca957600080fd5b634e487b7160e01b600052602160045260246000fdfe44656c65676174696f6e4d616e616765722e5f636f6d706c6574655175657565a2646970667358221220794b5c92c2b133ceda4be4341515834a97d52b26b6cf257dc5a843057bc3a70164736f6c634300080c0033","storage":{"0x0":"0xff"}},"0xc3e53f4d16ae77db1c982e75a937b9f60fe63690":{"nonce":1,"balance":"0x0","code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b600060405190815260200160405180910390f3fea264697066735822122007e2fd075a694b056e8bc9bef8c9f83d2b396b45d28a4f500d7d5cb1ef10012764736f6c634300080c0033","storage":{}},"0xcf7ed3acca5a467e9e704c703e8d87f634fb0fc9":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033","storage":{"0x0":"0x1","0x33":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x65":"0xe7f1725e7734ce288f8367e1bb143e90bb3f0512","0x66":"0x0","0x97":"0x831f01b2aeb61d5d8c019704e62c25763057a8806c5c790bc8b4c99ee54ac8a7","0x9d":"0x1","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0xb7f8bc63bbcad18155201308c8f3540b07f84f5e","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0xdc64a140aa3e981100a9beca4e685f962f0cf6c9":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033","storage":{"0x0":"0x1","0x33":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x97":"0xe7f1725e7734ce288f8367e1bb143e90bb3f0512","0x98":"0x0","0xc9":"0xd65ac9700cec4e530497617d02afdf0d5de3ed18466aca1578edcbce0d40ee16","0xcb":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0xa51c1fc2f0d1a1b8494ed1fe312d7c3a78ed91c0","0x74a9579f8366568b2792a7aa47988633896f9826ad6936da0f98ccff5c8ddab9":"0x0","0xac02fc4b95e25e4d2039d07a7ec79c323d4ec14f0cd7375b739e011a1bc7f187":"0x1","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0xe6e340d132b5f46d1e472debcd681b2abc16e57e":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806346fbf68e146100515780638568520614610089578063ce5484281461009e578063eab66d7a146100b1575b600080fd5b61007461005f366004610313565b60006020819052908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61009c610097366004610335565b6100dc565b005b61009c6100ac366004610313565b61011d565b6001546100c4906001600160a01b031681565b6040516001600160a01b039091168152602001610080565b6001546001600160a01b0316331461010f5760405162461bcd60e51b815260040161010690610371565b60405180910390fd5b6101198282610153565b5050565b6001546001600160a01b031633146101475760405162461bcd60e51b815260040161010690610371565b61015081610220565b50565b6001600160a01b0382166101bf5760405162461bcd60e51b815260206004820152602d60248201527f50617573657252656769737472792e5f7365745061757365723a207a65726f2060448201526c1859191c995cdcc81a5b9c1d5d609a1b6064820152608401610106565b6001600160a01b03821660008181526020818152604091829020805460ff19168515159081179091558251938452908301527f65d3a1fd4c13f05cba164f80d03ce90fb4b5e21946bfc3ab7dbd434c2d0b9152910160405180910390a15050565b6001600160a01b03811661028e5760405162461bcd60e51b815260206004820152602f60248201527f50617573657252656769737472792e5f736574556e7061757365723a207a657260448201526e1bc81859191c995cdcc81a5b9c1d5d608a1b6064820152608401610106565b600154604080516001600160a01b03928316815291831660208301527f06b4167a2528887a1e97a366eefe8549bfbf1ea3e6ac81cb2564a934d20e8892910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160a01b038116811461030e57600080fd5b919050565b60006020828403121561032557600080fd5b61032e826102f7565b9392505050565b6000806040838503121561034857600080fd5b610351836102f7565b91506020830135801515811461036657600080fd5b809150509250929050565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b60608201526080019056fea2646970667358221220f949639de16c13e62f22bfdc1313090a0debffbaac921ddb4832023f349c81e464736f6c634300080c0033","storage":{"0x1":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x723077b8a1b173adc35e5f0e7e3662fd1208212cb629f9c128551ea7168da722":"0x1"}},"0xe7f1725e7734ce288f8367e1bb143e90bb3f0512":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806346fbf68e146100515780638568520614610089578063ce5484281461009e578063eab66d7a146100b1575b600080fd5b61007461005f366004610313565b60006020819052908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61009c610097366004610335565b6100dc565b005b61009c6100ac366004610313565b61011d565b6001546100c4906001600160a01b031681565b6040516001600160a01b039091168152602001610080565b6001546001600160a01b0316331461010f5760405162461bcd60e51b815260040161010690610371565b60405180910390fd5b6101198282610153565b5050565b6001546001600160a01b031633146101475760405162461bcd60e51b815260040161010690610371565b61015081610220565b50565b6001600160a01b0382166101bf5760405162461bcd60e51b815260206004820152602d60248201527f50617573657252656769737472792e5f7365745061757365723a207a65726f2060448201526c1859191c995cdcc81a5b9c1d5d609a1b6064820152608401610106565b6001600160a01b03821660008181526020818152604091829020805460ff19168515159081179091558251938452908301527f65d3a1fd4c13f05cba164f80d03ce90fb4b5e21946bfc3ab7dbd434c2d0b9152910160405180910390a15050565b6001600160a01b03811661028e5760405162461bcd60e51b815260206004820152602f60248201527f50617573657252656769737472792e5f736574556e7061757365723a207a657260448201526e1bc81859191c995cdcc81a5b9c1d5d608a1b6064820152608401610106565b600154604080516001600160a01b03928316815291831660208301527f06b4167a2528887a1e97a366eefe8549bfbf1ea3e6ac81cb2564a934d20e8892910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160a01b038116811461030e57600080fd5b919050565b60006020828403121561032557600080fd5b61032e826102f7565b9392505050565b6000806040838503121561034857600080fd5b610351836102f7565b91506020830135801515811461036657600080fd5b809150509250929050565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b60608201526080019056fea264697066735822122082c17cbba412d9a44621d8a07946e79322d6248e2e7c652573dcc2c61babeb8c64736f6c634300080c0033","storage":{"0x1":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x723077b8a1b173adc35e5f0e7e3662fd1208212cb629f9c128551ea7168da722":"0x1"}},"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266":{"nonce":51,"balance":"0x21e1950f2b1cd57ef0a","code":"0x","storage":{}},"0xf5059a5d33d5853360d16c683c16e67980206f36":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122007c3990e071012e67e928be8d71cb1c6b5ed96fee92e98c9e70cc231dee7232064736f6c634300080c0033","storage":{"0xeb5be412f275a18f6e4d622aee4ff40b21467c926224771b782d4c095d1444b":"0x5","0x17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec":"0x1","0x295841a49a1089f4b560f91cfbb0133326654dcbb1041861fc5dde96c724a22f":"0x9635f643e140090a9a8dcd712ed6285858cebef","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x998abeb3e57409262ae5b751f60747921b33613e","0x3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff":"0x1","0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49":"0x1","0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5":"0x0","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x67d269191c92caf3cd7723f116c85e6e9bf55933","0xcfb339bd1c51c488f6134f4ac63d1594afad827b3401c3fc51ed1da74a8ca14e":"0xde0b6b3a764000009635f643e140090a9a8dcd712ed6285858cebef"}}}} \ No newline at end of file diff --git a/temp-incredible-squaring-avs/tests/anvil/deploy-avs-save-anvil-state.sh b/temp-incredible-squaring-avs/tests/anvil/deploy-avs-save-anvil-state.sh new file mode 100755 index 0000000..a1a5937 --- /dev/null +++ b/temp-incredible-squaring-avs/tests/anvil/deploy-avs-save-anvil-state.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +RPC_URL=http://localhost:8545 +PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + +# cd to the directory of this script so that this can be run from anywhere +parent_path=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + pwd -P +) +cd "$parent_path" + +set -a +source ./utils.sh +set +a + +cleanup() { + echo "Executing cleanup function..." + set +e + docker rm -f anvil + exit_status=$? + if [ $exit_status -ne 0 ]; then + echo "Script exited due to set -e on line $1 with command '$2'. Exit status: $exit_status" + fi +} +trap 'cleanup $LINENO "$BASH_COMMAND"' EXIT + +# start an anvil instance in the background that has eigenlayer contracts deployed +start_anvil_docker $parent_path/eigenlayer-deployed-anvil-state.json $parent_path/avs-and-eigenlayer-deployed-anvil-state.json + +cd ../../contracts +forge script script/IncredibleSquaringDeployer.s.sol --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast -v +# save the block-number in the genesis file which we also need to restart the anvil chain at the correct block +# otherwise the indexRegistry has a quorumUpdate at a high block number, and when we restart a clean anvil (without genesis.json) file +# it starts at block 0, and so calling getOperatorListAtBlockNumber reverts because it thinks there are no quorums registered at block 0 +# EDIT: this doesn't actually work... since we can't both load a state and a genesis.json file... see https://github.com/foundry-rs/foundry/issues/6679 +# will keep here in case this PR ever gets merged. +GENESIS_FILE=$parent_path/genesis.json +TMP_GENESIS_FILE=$parent_path/genesis.json.tmp +jq '.number = "'$(cast block-number)'"' $GENESIS_FILE >$TMP_GENESIS_FILE +mv $TMP_GENESIS_FILE $GENESIS_FILE + +# we also do this here to make sure the operator has funds to register with the eigenlayer contracts +cast send 0x860B6912C2d0337ef05bbC89b0C2CB6CbAEAB4A5 --value 10ether --private-key 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6 diff --git a/temp-incredible-squaring-avs/tests/anvil/deploy-eigenlayer-save-anvil-state.sh b/temp-incredible-squaring-avs/tests/anvil/deploy-eigenlayer-save-anvil-state.sh new file mode 100755 index 0000000..1afc55e --- /dev/null +++ b/temp-incredible-squaring-avs/tests/anvil/deploy-eigenlayer-save-anvil-state.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# cd to the directory of this script so that this can be run from anywhere +parent_path=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + pwd -P +) +# At this point we are in tests/anvil +cd "$parent_path" + +set -a +source ./utils.sh +set +a + +cleanup() { + echo "Executing cleanup function..." + set +e + docker rm -f anvil + exit_status=$? + if [ $exit_status -ne 0 ]; then + echo "Script exited due to set -e on line $1 with command '$2'. Exit status: $exit_status" + fi +} +trap 'cleanup $LINENO "$BASH_COMMAND"' EXIT + +# start an empty anvil chain in the background and dump its state to a json file upon exit +start_anvil_docker "" $parent_path/eigenlayer-deployed-anvil-state.json + +cd ../../contracts/lib/eigenlayer-middleware/lib/eigenlayer-contracts +# deployment overwrites this file, so we save it as backup, because we want that output in our local files, and not in the eigenlayer-contracts submodule files +mv script/output/devnet/M2_from_scratch_deployment_data.json script/output/devnet/M2_from_scratch_deployment_data.json.bak +# M2_Deploy_From_Scratch.s.sol prepends "script/testing/" to the configFile passed as input (M2_deploy_from_scratch.anvil.config.json) +forge script script/deploy/devnet/M2_Deploy_From_Scratch.s.sol --rpc-url http://localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --broadcast --sig "run(string memory configFile)" -- M2_deploy_from_scratch.anvil.config.json +mv script/output/devnet/M2_from_scratch_deployment_data.json ../../../../script/output/31337/eigenlayer_deployment_output.json +mv script/output/devnet/M2_from_scratch_deployment_data.json.bak script/output/devnet/M2_from_scratch_deployment_data.json diff --git a/temp-incredible-squaring-avs/tests/anvil/eigenlayer-deployed-anvil-state.json b/temp-incredible-squaring-avs/tests/anvil/eigenlayer-deployed-anvil-state.json new file mode 100644 index 0000000..ac582d0 --- /dev/null +++ b/temp-incredible-squaring-avs/tests/anvil/eigenlayer-deployed-anvil-state.json @@ -0,0 +1 @@ +{"accounts":{"0x0000000000000000000000000000000000000000":{"nonce":0,"balance":"0x0","code":"0x","storage":{}},"0x0165878a594ca255338adfa4d48449f69242eb8f":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033","storage":{"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x9a676e781a523b5d0c0e43731313a708cb607508","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0x0b306bf915c4d645ff596e518faf3f9669b97016":{"nonce":1,"balance":"0x0","code":"0x6080604052600436106101ee5760003560e01c80638da5cb5b1161010d578063c052bd61116100a0578063d1c64cc91161006f578063d1c64cc914610604578063ea4d3c9b14610624578063f2fde38b14610658578063f6848d2414610678578063fabc1cbc146106b357600080fd5b8063c052bd6114610584578063c1de3aef146105a4578063c2c51c40146105c4578063cf756fdf146105e457600080fd5b8063a38406a3116100dc578063a38406a3146104fa578063a6a509be1461051a578063b134427114610530578063beffbb891461056457600080fd5b80638da5cb5b1461046b5780639104c319146104895780639b4e4634146104b15780639ba06275146104c457600080fd5b8063595c6a6711610185578063715018a611610154578063715018a6146103ed57806374cdd7981461040257806384d8106214610436578063886f11951461044b57600080fd5b8063595c6a67146103565780635ac86ab71461036b5780635c975abb146103ab57806360f4062b146103c057600080fd5b8063387b1300116101c1578063387b1300146102b457806339b70e38146102d457806344e71c8014610308578063463db0381461033657600080fd5b80630e81073c146101f357806310d67a2f14610226578063136439dd14610248578063292b7b2b14610268575b600080fd5b3480156101ff57600080fd5b5061021361020e366004612406565b6106d3565b6040519081526020015b60405180910390f35b34801561023257600080fd5b50610246610241366004612432565b610911565b005b34801561025457600080fd5b5061024661026336600461244f565b6109c4565b34801561027457600080fd5b5061029c7f000000000000000000000000610178da211fef7d417bc0e6fed39f05609ad78881565b6040516001600160a01b03909116815260200161021d565b3480156102c057600080fd5b506102466102cf366004612468565b610b03565b3480156102e057600080fd5b5061029c7f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c981565b34801561031457600080fd5b5061031d610ea1565b60405167ffffffffffffffff909116815260200161021d565b34801561034257600080fd5b506102466103513660046124a9565b610eca565b34801561036257600080fd5b50610246611056565b34801561037757600080fd5b5061039b6103863660046124d3565b606654600160ff9092169190911b9081161490565b604051901515815260200161021d565b3480156103b757600080fd5b50606654610213565b3480156103cc57600080fd5b506102136103db366004612432565b609b6020526000908152604090205481565b3480156103f957600080fd5b5061024661111d565b34801561040e57600080fd5b5061029c7f00000000000000000000000000000000219ab540356cbb839cbe05303d7705fa81565b34801561044257600080fd5b5061029c611131565b34801561045757600080fd5b5060655461029c906001600160a01b031681565b34801561047757600080fd5b506033546001600160a01b031661029c565b34801561049557600080fd5b5061029c73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac081565b6102466104bf36600461253f565b61121b565b3480156104d057600080fd5b5061029c6104df366004612432565b6098602052600090815260409020546001600160a01b031681565b34801561050657600080fd5b5061029c610515366004612432565b61130a565b34801561052657600080fd5b5061021360995481565b34801561053c57600080fd5b5061029c7f0000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f81565b34801561057057600080fd5b5061024661057f366004612406565b6113dc565b34801561059057600080fd5b5060975461029c906001600160a01b031681565b3480156105b057600080fd5b506102466105bf366004612432565b6115f3565b3480156105d057600080fd5b506102466105df366004612406565b611604565b3480156105f057600080fd5b506102466105ff3660046125b3565b611a07565b34801561061057600080fd5b5061021361061f3660046124a9565b611b30565b34801561063057600080fd5b5061029c7f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc981565b34801561066457600080fd5b50610246610673366004612432565b611c3b565b34801561068457600080fd5b5061039b610693366004612432565b6001600160a01b0390811660009081526098602052604090205416151590565b3480156106bf57600080fd5b506102466106ce36600461244f565b611cb1565b6000336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc916146107265760405162461bcd60e51b815260040161071d90612604565b60405180910390fd5b6001600160a01b0383166107a25760405162461bcd60e51b815260206004820152603a60248201527f456967656e506f644d616e616765722e6164645368617265733a20706f644f7760448201527f6e65722063616e6e6f74206265207a65726f2061646472657373000000000000606482015260840161071d565b60008212156108105760405162461bcd60e51b815260206004820152603460248201527f456967656e506f644d616e616765722e6164645368617265733a207368617265604482015273732063616e6e6f74206265206e6567617469766560601b606482015260840161071d565b61081e633b9aca0083612678565b156108915760405162461bcd60e51b815260206004820152603d60248201527f456967656e506f644d616e616765722e6164645368617265733a20736861726560448201527f73206d75737420626520612077686f6c65204777656920616d6f756e74000000606482015260840161071d565b6001600160a01b0383166000908152609b6020526040812054906108b584836126a2565b6001600160a01b0386166000818152609b6020526040908190208390555191925090600080516020613231833981519152906108f49087815260200190565b60405180910390a26109068282611e0d565b925050505b92915050565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610964573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098891906126e3565b6001600160a01b0316336001600160a01b0316146109b85760405162461bcd60e51b815260040161071d90612700565b6109c181611e4f565b50565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610a0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a30919061274a565b610a4c5760405162461bcd60e51b815260040161071d9061276c565b60665481811614610ac55760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c6974790000000000000000606482015260840161071d565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc91614610b4b5760405162461bcd60e51b815260040161071d90612604565b6001600160a01b038316610bc55760405162461bcd60e51b8152602060048201526047602482015260008051602061325183398151915260448201527f546f6b656e733a20706f644f776e65722063616e6e6f74206265207a65726f206064820152666164647265737360c81b608482015260a40161071d565b6001600160a01b038216610c425760405162461bcd60e51b815260206004820152604a602482015260008051602061325183398151915260448201527f546f6b656e733a2064657374696e6174696f6e2063616e6e6f74206265207a65606482015269726f206164647265737360b01b608482015260a40161071d565b6000811215610cb15760405162461bcd60e51b8152602060048201526041602482015260008051602061325183398151915260448201527f546f6b656e733a207368617265732063616e6e6f74206265206e6567617469766064820152606560f81b608482015260a40161071d565b610cbf633b9aca0082612678565b15610d335760405162461bcd60e51b815260206004820152604a602482015260008051602061325183398151915260448201527f546f6b656e733a20736861726573206d75737420626520612077686f6c6520476064820152691dd95a48185b5bdd5b9d60b21b608482015260a40161071d565b6001600160a01b0383166000908152609b602052604081205490811215610e26576000610d5f826127b4565b905080831115610dc4576001600160a01b0385166000908152609b6020526040812055610d8c81846127d1565b9250846001600160a01b031660008051602061323183398151915282604051610db791815260200190565b60405180910390a2610e24565b6001600160a01b0385166000908152609b602052604081208054859290610dec9084906126a2565b90915550506040518381526001600160a01b038616906000805160206132318339815191529060200160405180910390a25050505050565b505b6001600160a01b03848116600090815260986020526040908190205490516362483a2160e11b815285831660048201526024810185905291169063c490744290604401600060405180830381600087803b158015610e8357600080fd5b505af1158015610e97573d6000803e3d6000fd5b5050505050505050565b609c5460009067ffffffffffffffff1680610ec55767ffffffffffffffff91505090565b919050565b610ed2611f46565b67ffffffffffffffff8116610f645760405162461bcd60e51b815260206004820152604c60248201527f456967656e506f644d616e616765722e73657444656e6562466f726b54696d6560448201527f7374616d703a2063616e6e6f7420736574206e657744656e6562466f726b546960648201526b06d657374616d7020746f20360a41b608482015260a40161071d565b609c5467ffffffffffffffff16156110005760405162461bcd60e51b815260206004820152605360248201527f456967656e506f644d616e616765722e73657444656e6562466f726b54696d6560448201527f7374616d703a2063616e6e6f74207365742064656e6562466f726b54696d657360648201527274616d70206d6f7265207468616e206f6e636560681b608482015260a40161071d565b609c805467ffffffffffffffff191667ffffffffffffffff83169081179091556040519081527f19200b6fdad58f91b2f496b0c444fc4be3eff74a7e24b07770e04a7137bfd9db9060200160405180910390a150565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa15801561109e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c2919061274a565b6110de5760405162461bcd60e51b815260040161071d9061276c565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b611125611f46565b61112f6000611fa0565b565b6066546000908190600190811614156111885760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b604482015260640161071d565b336000908152609860205260409020546001600160a01b03161561120a5760405162461bcd60e51b815260206004820152603360248201527f456967656e506f644d616e616765722e637265617465506f643a2053656e64656044820152721c88185b1c9958591e481a185cc818481c1bd9606a1b606482015260840161071d565b6000611214611ff2565b9250505090565b606654600090600190811614156112705760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b604482015260640161071d565b336000908152609860205260409020546001600160a01b03168061129957611296611ff2565b90505b6040516326d3918d60e21b81526001600160a01b03821690639b4e46349034906112cf908b908b908b908b908b90600401612811565b6000604051808303818588803b1580156112e857600080fd5b505af11580156112fc573d6000803e3d6000fd5b505050505050505050505050565b6001600160a01b038082166000908152609860205260408120549091168061090b576113d5836001600160a01b031660001b60405180610940016040528061090e815260200161292361090e9139604080516001600160a01b037f000000000000000000000000610178da211fef7d417bc0e6fed39f05609ad788166020820152808201919091526000606082015260800160408051601f19818403018152908290526113ba9291602001612886565b60405160208183030381529060405280519060200120612157565b9392505050565b336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc916146114245760405162461bcd60e51b815260040161071d90612604565b600081121561149b5760405162461bcd60e51b815260206004820152603760248201527f456967656e506f644d616e616765722e72656d6f76655368617265733a20736860448201527f617265732063616e6e6f74206265206e65676174697665000000000000000000606482015260840161071d565b6114a9633b9aca0082612678565b1561151e576040805162461bcd60e51b81526020600482015260248101919091527f456967656e506f644d616e616765722e72656d6f76655368617265733a20736860448201527f61726573206d75737420626520612077686f6c65204777656920616d6f756e74606482015260840161071d565b6001600160a01b0382166000908152609b602052604081205461154290839061289b565b905060008112156115d35760405162461bcd60e51b815260206004820152604f60248201527f456967656e506f644d616e616765722e72656d6f76655368617265733a20636160448201527f6e6e6f7420726573756c7420696e20706f64206f776e657220686176696e672060648201526e6e656761746976652073686172657360881b608482015260a40161071d565b6001600160a01b039092166000908152609b602052604090209190915550565b6115fb611f46565b6109c1816121b3565b6001600160a01b03808316600090815260986020526040902054839116331461167f5760405162461bcd60e51b815260206004820152602760248201527f456967656e506f644d616e616765722e6f6e6c79456967656e506f643a206e6f6044820152661d0818481c1bd960ca1b606482015260840161071d565b600260c95414156116d25760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161071d565b600260c9556001600160a01b03831661176e5760405162461bcd60e51b815260206004820152605260248201527f456967656e506f644d616e616765722e7265636f7264426561636f6e4368616960448201527f6e45544842616c616e63655570646174653a20706f644f776e65722063616e6e6064820152716f74206265207a65726f206164647265737360701b608482015260a40161071d565b61177c633b9aca00836128da565b156118155760405162461bcd60e51b815260206004820152605a60248201527f456967656e506f644d616e616765722e7265636f7264426561636f6e4368616960448201527f6e45544842616c616e63655570646174653a2073686172657344656c7461206d60648201527f75737420626520612077686f6c65204777656920616d6f756e74000000000000608482015260a40161071d565b6001600160a01b0383166000908152609b60205260408120549061183984836126a2565b6001600160a01b0386166000908152609b602052604081208290559091506118618383611e0d565b905080156119c957600081121561192c576001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc91663132d49678773beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06118c0856127b4565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561190f57600080fd5b505af1158015611923573d6000803e3d6000fd5b505050506119c9565b604051631452b9d760e11b81526001600160a01b03878116600483015273beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06024830152604482018390527f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc916906328a573ae90606401600060405180830381600087803b1580156119b057600080fd5b505af11580156119c4573d6000803e3d6000fd5b505050505b856001600160a01b0316600080516020613231833981519152866040516119f291815260200190565b60405180910390a25050600160c95550505050565b600054610100900460ff1615808015611a275750600054600160ff909116105b80611a415750303b158015611a41575060005460ff166001145b611aa45760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161071d565b6000805460ff191660011790558015611ac7576000805461ff0019166101001790555b611ad0856121b3565b611ad984611fa0565b611ae383836121fd565b8015611b29576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60975460405163321accf960e11b815267ffffffffffffffff8316600482015260009182916001600160a01b039091169063643599f290602401602060405180830381865afa158015611b87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bab91906128ee565b90508061090b5760405162461bcd60e51b815260206004820152605260248201527f456967656e506f644d616e616765722e676574426c6f636b526f6f744174546960448201527f6d657374616d703a20737461746520726f6f742061742074696d657374616d70606482015271081b9bdd081e595d08199a5b985b1a5e995960721b608482015260a40161071d565b611c43611f46565b6001600160a01b038116611ca85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161071d565b6109c181611fa0565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2891906126e3565b6001600160a01b0316336001600160a01b031614611d585760405162461bcd60e51b815260040161071d90612700565b606654198119606654191614611dd65760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c6974790000000000000000606482015260840161071d565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610af8565b6000808313611e2d5760008213611e265750600061090b565b508061090b565b60008213611e4557611e3e836127b4565b905061090b565b611e3e838361289b565b6001600160a01b038116611edd5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a40161071d565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b0316331461112f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161071d565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060996000815461200390612907565b9091555060408051610940810190915261090e8082526000916120a291839133916129236020830139604080516001600160a01b037f000000000000000000000000610178da211fef7d417bc0e6fed39f05609ad788166020820152808201919091526000606082015260800160408051601f198184030181529082905261208e9291602001612886565b6040516020818303038152906040526122e7565b60405163189acdbd60e31b81523360048201529091506001600160a01b0382169063c4d66de890602401600060405180830381600087803b1580156120e657600080fd5b505af11580156120fa573d6000803e3d6000fd5b50503360008181526098602052604080822080546001600160a01b0319166001600160a01b038816908117909155905192945092507f21c99d0db02213c32fff5b05cf0a718ab5f858802b91498f80d82270289d856a91a3919050565b604080516001600160f81b03196020808301919091526bffffffffffffffffffffffff193060601b16602183015260358201859052605580830185905283518084039091018152607590920190925280519101206000906113d5565b609780546001600160a01b0319166001600160a01b0383169081179091556040517f08f0470754946ccfbb446ff7fd2d6ae6af1bbdae19f85794c0cc5ed5e8ceb4f690600090a250565b6065546001600160a01b031615801561221e57506001600160a01b03821615155b6122a05760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a40161071d565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a26122e382611e4f565b5050565b6000808447101561233a5760405162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e6365000000604482015260640161071d565b82516123885760405162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f604482015260640161071d565b8383516020850187f590506001600160a01b0381166123e95760405162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f7900000000000000604482015260640161071d565b949350505050565b6001600160a01b03811681146109c157600080fd5b6000806040838503121561241957600080fd5b8235612424816123f1565b946020939093013593505050565b60006020828403121561244457600080fd5b81356113d5816123f1565b60006020828403121561246157600080fd5b5035919050565b60008060006060848603121561247d57600080fd5b8335612488816123f1565b92506020840135612498816123f1565b929592945050506040919091013590565b6000602082840312156124bb57600080fd5b813567ffffffffffffffff811681146113d557600080fd5b6000602082840312156124e557600080fd5b813560ff811681146113d557600080fd5b60008083601f84011261250857600080fd5b50813567ffffffffffffffff81111561252057600080fd5b60208301915083602082850101111561253857600080fd5b9250929050565b60008060008060006060868803121561255757600080fd5b853567ffffffffffffffff8082111561256f57600080fd5b61257b89838a016124f6565b9097509550602088013591508082111561259457600080fd5b506125a1888289016124f6565b96999598509660400135949350505050565b600080600080608085870312156125c957600080fd5b84356125d4816123f1565b935060208501356125e4816123f1565b925060408501356125f4816123f1565b9396929550929360600135925050565b602080825260409082018190527f456967656e506f644d616e616765722e6f6e6c7944656c65676174696f6e4d61908201527f6e616765723a206e6f74207468652044656c65676174696f6e4d616e61676572606082015260800190565b634e487b7160e01b600052601260045260246000fd5b60008261268757612687612662565b500690565b634e487b7160e01b600052601160045260246000fd5b600080821280156001600160ff1b03849003851316156126c4576126c461268c565b600160ff1b83900384128116156126dd576126dd61268c565b50500190565b6000602082840312156126f557600080fd5b81516113d5816123f1565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b60006020828403121561275c57600080fd5b815180151581146113d557600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b6000600160ff1b8214156127ca576127ca61268c565b5060000390565b6000828210156127e3576127e361268c565b500390565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6060815260006128256060830187896127e8565b82810360208401526128388186886127e8565b9150508260408301529695505050505050565b6000815160005b8181101561286c5760208185018101518683015201612852565b8181111561287b576000828601525b509290920192915050565b60006123e9612895838661284b565b8461284b565b60008083128015600160ff1b8501841216156128b9576128b961268c565b6001600160ff1b03840183138116156128d4576128d461268c565b50500390565b6000826128e9576128e9612662565b500790565b60006020828403121561290057600080fd5b5051919050565b600060001982141561291b5761291b61268c565b506001019056fe608060405260405161090e38038061090e83398101604081905261002291610460565b61002e82826000610035565b505061058a565b61003e83610100565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100fb576100f9836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e99190610520565b836102a360201b6100291760201c565b505b505050565b610113816102cf60201b6100551760201c565b6101725760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101e6816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d79190610520565b6102cf60201b6100551760201c565b61024b5760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610169565b806102827fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5060001b6102de60201b6100641760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606102c883836040518060600160405280602781526020016108e7602791396102e1565b9392505050565b6001600160a01b03163b151590565b90565b6060600080856001600160a01b0316856040516102fe919061053b565b600060405180830381855af49150503d8060008114610339576040519150601f19603f3d011682016040523d82523d6000602084013e61033e565b606091505b5090925090506103508683838761035a565b9695505050505050565b606083156103c65782516103bf576001600160a01b0385163b6103bf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610169565b50816103d0565b6103d083836103d8565b949350505050565b8151156103e85781518083602001fd5b8060405162461bcd60e51b81526004016101699190610557565b80516001600160a01b038116811461041957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561044f578181015183820152602001610437565b838111156100f95750506000910152565b6000806040838503121561047357600080fd5b61047c83610402565b60208401519092506001600160401b038082111561049957600080fd5b818501915085601f8301126104ad57600080fd5b8151818111156104bf576104bf61041e565b604051601f8201601f19908116603f011681019083821181831017156104e7576104e761041e565b8160405282815288602084870101111561050057600080fd5b610511836020830160208801610434565b80955050505050509250929050565b60006020828403121561053257600080fd5b6102c882610402565b6000825161054d818460208701610434565b9190910192915050565b6020815260008251806020840152610576816040850160208701610434565b601f01601f19169190910160400192915050565b61034e806105996000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610067565b610100565b565b606061004e83836040518060600160405280602781526020016102f260279139610124565b9392505050565b6001600160a01b03163b151590565b90565b600061009a7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fb9190610249565b905090565b3660008037600080366000845af43d6000803e80801561011f573d6000f35b3d6000fd5b6060600080856001600160a01b03168560405161014191906102a2565b600060405180830381855af49150503d806000811461017c576040519150601f19603f3d011682016040523d82523d6000602084013e610181565b606091505b50915091506101928683838761019c565b9695505050505050565b6060831561020d578251610206576001600160a01b0385163b6102065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610217565b610217838361021f565b949350505050565b81511561022f5781518083602001fd5b8060405162461bcd60e51b81526004016101fd91906102be565b60006020828403121561025b57600080fd5b81516001600160a01b038116811461004e57600080fd5b60005b8381101561028d578181015183820152602001610275565b8381111561029c576000848401525b50505050565b600082516102b4818460208701610272565b9190910192915050565b60208152600082518060208401526102dd816040850160208701610272565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220d51e81d3bc5ed20a26aeb05dce7e825c503b2061aa78628027300c8d65b9d89a64736f6c634300080c0033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c65644e2b791dedccd9fb30141b088cabf5c14a8912b52f59375c95c010700b8c6193456967656e506f644d616e616765722e77697468647261775368617265734173a26469706673582212202fb67ee19715abe3d5c61e540dac4e2199f3eb1e931e0d03ff1fd7e29bcee5f764736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x0dcd1bf9a1b36ce34237eeafef220932846bcd82":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106101425760003560e01c80638da5cb5b116100b8578063d79aceab1161007c578063d79aceab146102f8578063df5cf7231461031f578063ec76f44214610346578063f2fde38b14610359578063f698da251461036c578063fabc1cbc1461037457600080fd5b80638da5cb5b1461029b5780639926ee7d146102ac578063a1060c88146102bf578063a364f4da146102d2578063a98fb355146102e557600080fd5b806349075da31161010a57806349075da3146101fa578063595c6a67146102355780635ac86ab71461023d5780635c975abb14610260578063715018a614610268578063886f11951461027057600080fd5b806310d67a2f14610147578063136439dd1461015c5780631794bb3c1461016f57806320606b7014610182578063374823b5146101bc575b600080fd5b61015a6101553660046118ab565b610387565b005b61015a61016a3660046118cf565b610443565b61015a61017d3660046118e8565b610582565b6101a97f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6040519081526020015b60405180910390f35b6101ea6101ca366004611929565b609960209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016101b3565b610228610208366004611955565b609860209081526000928352604080842090915290825290205460ff1681565b6040516101b391906119a4565b61015a6106ac565b6101ea61024b3660046119cc565b606654600160ff9092169190911b9081161490565b6066546101a9565b61015a610773565b606554610283906001600160a01b031681565b6040516001600160a01b0390911681526020016101b3565b6033546001600160a01b0316610283565b61015a6102ba366004611a5f565b610787565b6101a96102cd366004611b46565b610b1a565b61015a6102e03660046118ab565b610bd3565b61015a6102f3366004611b8c565b610d3c565b6101a97fda2c89bafdd34776a2b8bb9c83c82f419e20cc8c67207f70edd58249b92661bd81565b6102837f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc981565b61015a6103543660046118cf565b610d83565b61015a6103673660046118ab565b610e2e565b6101a9610ea4565b61015a6103823660046118cf565b610ee2565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103fe9190611bfe565b6001600160a01b0316336001600160a01b0316146104375760405162461bcd60e51b815260040161042e90611c1b565b60405180910390fd5b6104408161103e565b50565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa15801561048b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104af9190611c65565b6104cb5760405162461bcd60e51b815260040161042e90611c87565b606654818116146105445760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c6974790000000000000000606482015260840161042e565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b600054610100900460ff16158080156105a25750600054600160ff909116105b806105bc5750303b1580156105bc575060005460ff166001145b61061f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161042e565b6000805460ff191660011790558015610642576000805461ff0019166101001790555b61064c8383611135565b61065461121f565b609755610660846112b6565b80156106a6576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156106f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107189190611c65565b6107345760405162461bcd60e51b815260040161042e90611c87565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b61077b611308565b61078560006112b6565b565b606654600090600190811614156107dc5760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b604482015260640161042e565b42826040015110156108445760405162461bcd60e51b815260206004820152603e6024820152600080516020611dac83398151915260448201527f56533a206f70657261746f72207369676e617475726520657870697265640000606482015260840161042e565b60013360009081526098602090815260408083206001600160a01b038816845290915290205460ff16600181111561087e5761087e61198e565b14156108e05760405162461bcd60e51b815260206004820152603f6024820152600080516020611dac83398151915260448201527f56533a206f70657261746f7220616c7265616479207265676973746572656400606482015260840161042e565b6001600160a01b038316600090815260996020908152604080832085830151845290915290205460ff16156109645760405162461bcd60e51b81526020600482015260366024820152600080516020611dac8339815191526044820152751594ce881cd85b1d08185b1c9958591e481cdc195b9d60521b606482015260840161042e565b6040516336b87bd760e11b81526001600160a01b0384811660048301527f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc91690636d70f7ae90602401602060405180830381865afa1580156109ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ee9190611c65565b610a645760405162461bcd60e51b815260206004820152604d6024820152600080516020611dac83398151915260448201527f56533a206f70657261746f72206e6f74207265676973746572656420746f204560648201526c1a59d95b93185e595c881e595d609a1b608482015260a40161042e565b6000610a7a843385602001518660400151610b1a565b9050610a8b84828560000151611362565b3360008181526098602090815260408083206001600160a01b0389168085529083528184208054600160ff199182168117909255609985528386208a860151875290945293829020805490931684179092555190917ff0952b1c65271d819d39983d2abb044b9cace59bcc4d4dd389f586ebdcb15b4191610b0c91906119a4565b60405180910390a350505050565b604080517fda2c89bafdd34776a2b8bb9c83c82f419e20cc8c67207f70edd58249b92661bd6020808301919091526001600160a01b0387811683850152861660608301526080820185905260a08083018590528351808403909101815260c0909201909252805191012060009081610b90610ea4565b60405161190160f01b602082015260228101919091526042810183905260620160408051808303601f190181529190528051602090910120979650505050505050565b60665460009060019081161415610c285760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b604482015260640161042e565b60013360009081526098602090815260408083206001600160a01b038716845290915290205460ff166001811115610c6257610c6261198e565b14610cd55760405162461bcd60e51b815260206004820152603f60248201527f4156534469726563746f72792e646572656769737465724f70657261746f724660448201527f726f6d4156533a206f70657261746f72206e6f74207265676973746572656400606482015260840161042e565b3360008181526098602090815260408083206001600160a01b0387168085529252808320805460ff191690555190917ff0952b1c65271d819d39983d2abb044b9cace59bcc4d4dd389f586ebdcb15b4191610d3091906119a4565b60405180910390a35050565b336001600160a01b03167fa89c1dc243d8908a96dd84944bcc97d6bc6ac00dd78e20621576be6a3c9437138383604051610d77929190611ccf565b60405180910390a25050565b33600090815260996020908152604080832084845290915290205460ff1615610e085760405162461bcd60e51b815260206004820152603160248201527f4156534469726563746f72792e63616e63656c53616c743a2063616e6e6f742060448201527018d85b98d95b081cdc195b9d081cd85b1d607a1b606482015260840161042e565b33600090815260996020908152604080832093835292905220805460ff19166001179055565b610e36611308565b6001600160a01b038116610e9b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161042e565b610440816112b6565b60007f0000000000000000000000000000000000000000000000000000000000007a69461415610ed5575060975490565b610edd61121f565b905090565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f599190611bfe565b6001600160a01b0316336001600160a01b031614610f895760405162461bcd60e51b815260040161042e90611c1b565b6066541981196066541916146110075760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c6974790000000000000000606482015260840161042e565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c90602001610577565b6001600160a01b0381166110cc5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a40161042e565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b6065546001600160a01b031615801561115657506001600160a01b03821615155b6111d85760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a40161042e565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a261121b8261103e565b5050565b604080518082018252600a81526922b4b3b2b72630bcb2b960b11b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f71b625cfad44bac63b13dba07f2e1d6084ee04b6f8752101ece6126d584ee6ea81840152466060820152306080808301919091528351808303909101815260a0909101909252815191012090565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6033546001600160a01b031633146107855760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161042e565b6001600160a01b0383163b1561148157604051630b135d3f60e11b808252906001600160a01b03851690631626ba7e906113a29086908690600401611cfe565b602060405180830381865afa1580156113bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e39190611d5b565b6001600160e01b0319161461147c5760405162461bcd60e51b815260206004820152605360248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a2045524331323731207369676e6174757265206064820152721d995c9a599a58d85d1a5bdb8819985a5b1959606a1b608482015260a40161042e565b505050565b826001600160a01b03166114958383611521565b6001600160a01b03161461147c5760405162461bcd60e51b815260206004820152604760248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a207369676e6174757265206e6f742066726f6d6064820152661039b4b3b732b960c91b608482015260a40161042e565b60008060006115308585611545565b9150915061153d816115b5565b509392505050565b60008082516041141561157c5760208301516040840151606085015160001a61157087828585611770565b945094505050506115ae565b8251604014156115a6576020830151604084015161159b86838361185d565b9350935050506115ae565b506000905060025b9250929050565b60008160048111156115c9576115c961198e565b14156115d25750565b60018160048111156115e6576115e661198e565b14156116345760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161042e565b60028160048111156116485761164861198e565b14156116965760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161042e565b60038160048111156116aa576116aa61198e565b14156117035760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161042e565b60048160048111156117175761171761198e565b14156104405760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161042e565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156117a75750600090506003611854565b8460ff16601b141580156117bf57508460ff16601c14155b156117d05750600090506004611854565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611824573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661184d57600060019250925050611854565b9150600090505b94509492505050565b6000806001600160ff1b0383168161187a60ff86901c601b611d85565b905061188887828885611770565b935093505050935093915050565b6001600160a01b038116811461044057600080fd5b6000602082840312156118bd57600080fd5b81356118c881611896565b9392505050565b6000602082840312156118e157600080fd5b5035919050565b6000806000606084860312156118fd57600080fd5b833561190881611896565b9250602084013561191881611896565b929592945050506040919091013590565b6000806040838503121561193c57600080fd5b823561194781611896565b946020939093013593505050565b6000806040838503121561196857600080fd5b823561197381611896565b9150602083013561198381611896565b809150509250929050565b634e487b7160e01b600052602160045260246000fd5b60208101600283106119c657634e487b7160e01b600052602160045260246000fd5b91905290565b6000602082840312156119de57600080fd5b813560ff811681146118c857600080fd5b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715611a2857611a286119ef565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611a5757611a576119ef565b604052919050565b60008060408385031215611a7257600080fd5b8235611a7d81611896565b915060208381013567ffffffffffffffff80821115611a9b57600080fd5b9085019060608288031215611aaf57600080fd5b611ab7611a05565b823582811115611ac657600080fd5b8301601f81018913611ad757600080fd5b803583811115611ae957611ae96119ef565b611afb601f8201601f19168701611a2e565b93508084528986828401011115611b1157600080fd5b808683018786013760008682860101525050818152838301358482015260408301356040820152809450505050509250929050565b60008060008060808587031215611b5c57600080fd5b8435611b6781611896565b93506020850135611b7781611896565b93969395505050506040820135916060013590565b60008060208385031215611b9f57600080fd5b823567ffffffffffffffff80821115611bb757600080fd5b818501915085601f830112611bcb57600080fd5b813581811115611bda57600080fd5b866020828501011115611bec57600080fd5b60209290920196919550909350505050565b600060208284031215611c1057600080fd5b81516118c881611896565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215611c7757600080fd5b815180151581146118c857600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b82815260006020604081840152835180604085015260005b81811015611d3257858101830151858201606001528201611d16565b81811115611d44576000606083870101525b50601f01601f191692909201606001949350505050565b600060208284031215611d6d57600080fd5b81516001600160e01b0319811681146118c857600080fd5b60008219821115611da657634e487b7160e01b600052601160045260246000fd5b50019056fe4156534469726563746f72792e72656769737465724f70657261746f72546f41a2646970667358221220b9f71d6d6e6e7c7b30ff4dea984c6d2424f2635bfd916d169a159ef73e00d98e64736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x14dc79964da2c08b23698b3d3cc7ca32193d9955":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x15d34aaf54267db7d7c367839aaf71a00a2c6a65":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x2279b7a0a67db372996a5fab50d91eaa73d2ebe6":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033","storage":{"0x0":"0x1","0x33":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x97":"0xe7f1725e7734ce288f8367e1bb143e90bb3f0512","0x98":"0x0","0xc9":"0x1","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0x959922be3caee4b8cd9a407cc3ac1c251c2007b1","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x322813fd9a801c5507c9de605d63cea4f2ce6c44":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b506004361061018e5760003560e01c80635c975abb116100de578063ab5921e111610097578063df6fadc111610071578063df6fadc114610366578063e3dae51c14610381578063f3e7387514610394578063fabc1cbc146103a757600080fd5b8063ab5921e11461032b578063ce7c2ac214610340578063d9caed121461035357600080fd5b80635c975abb146102c857806361b01b5d146102d05780637a8b2637146102d9578063886f1195146102ec5780638c871019146103055780638f6a62401461031857600080fd5b80633a98ef391161014b578063485cc95511610125578063485cc9551461026b578063553ca5f81461027e578063595c6a67146102915780635ac86ab71461029957600080fd5b80633a98ef391461023857806343fe08b01461024f57806347e7ef241461025857600080fd5b8063019e27291461019357806310d67a2f146101a857806311c70c9d146101bb578063136439dd146101ce5780632495a599146101e157806339b70e3814610211575b600080fd5b6101a66101a13660046117b8565b6103ba565b005b6101a66101b6366004611802565b61049d565b6101a66101c936600461181f565b610550565b6101a66101dc366004611841565b610605565b6032546101f4906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101f47f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c981565b61024160335481565b604051908152602001610208565b61024160645481565b61024161026636600461185a565b610749565b6101a6610279366004611886565b6108ed565b61024161028c366004611802565b6109bb565b6101a66109cf565b6102b86102a73660046118bf565b6001805460ff9092161b9081161490565b6040519015158152602001610208565b600154610241565b61024160655481565b6102416102e7366004611841565b610a9b565b6000546101f4906201000090046001600160a01b031681565b610241610313366004611841565b610ae6565b610241610326366004611802565b610af1565b610333610aff565b6040516102089190611912565b61024161034e366004611802565b610b1f565b6101a6610361366004611945565b610bb4565b60645460655460408051928352602083019190915201610208565b61024161038f366004611841565b610d7d565b6102416103a2366004611841565b610db6565b6101a66103b5366004611841565b610dc1565b600054610100900460ff16158080156103da5750600054600160ff909116105b806103f45750303b1580156103f4575060005460ff166001145b6104195760405162461bcd60e51b815260040161041090611986565b60405180910390fd5b6000805460ff19166001179055801561043c576000805461ff0019166101001790555b6104468585610f1d565b610450838361102a565b8015610496576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051491906119d4565b6001600160a01b0316336001600160a01b0316146105445760405162461bcd60e51b8152600401610410906119f1565b61054d816110bb565b50565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c791906119d4565b6001600160a01b0316336001600160a01b0316146105f75760405162461bcd60e51b8152600401610410906119f1565b6106018282610f1d565b5050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610652573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106769190611a3b565b6106925760405162461bcd60e51b815260040161041090611a5d565b6001548181161461070b5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610410565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6001805460009182918116141561079e5760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610410565b336001600160a01b037f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c916146108165760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e616765726044820152606401610410565b61082084846111c0565b60335460006108316103e883611abb565b905060006103e86108406112a2565b61084a9190611abb565b905060006108588783611ad3565b9050806108658489611aea565b61086f9190611b09565b9550856108d55760405162461bcd60e51b815260206004820152602e60248201527f5374726174656779426173652e6465706f7369743a206e65775368617265732060448201526d63616e6e6f74206265207a65726f60901b6064820152608401610410565b6108df8685611abb565b603355505050505092915050565b600054610100900460ff161580801561090d5750600054600160ff909116105b806109275750303b158015610927575060005460ff166001145b6109435760405162461bcd60e51b815260040161041090611986565b6000805460ff191660011790558015610966576000805461ff0019166101001790555b610970838361102a565b80156109b6576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006109c96102e783610b1f565b92915050565b60005460405163237dfb4760e11b8152336004820152620100009091046001600160a01b0316906346fbf68e90602401602060405180830381865afa158015610a1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a409190611a3b565b610a5c5760405162461bcd60e51b815260040161041090611a5d565b600019600181905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b6000806103e8603354610aae9190611abb565b905060006103e8610abd6112a2565b610ac79190611abb565b905081610ad48583611aea565b610ade9190611b09565b949350505050565b60006109c982610d7d565b60006109c96103a283610b1f565b60606040518060800160405280604d8152602001611b61604d9139905090565b604051633d3f06c960e11b81526001600160a01b0382811660048301523060248301526000917f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c990911690637a7e0d9290604401602060405180830381865afa158015610b90573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c99190611b2b565b6001805460029081161415610c075760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b6044820152606401610410565b336001600160a01b037f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c91614610c7f5760405162461bcd60e51b815260206004820181905260248201527f5374726174656779426173652e6f6e6c7953747261746567794d616e616765726044820152606401610410565b610c8a848484611314565b60335480831115610d195760405162461bcd60e51b815260206004820152604d60248201527f5374726174656779426173652e77697468647261773a20616d6f756e7453686160448201527f726573206d757374206265206c657373207468616e206f7220657175616c207460648201526c6f20746f74616c53686172657360981b608482015260a401610410565b6000610d276103e883611abb565b905060006103e8610d366112a2565b610d409190611abb565b9050600082610d4f8784611aea565b610d599190611b09565b9050610d658685611ad3565b603355610d73888883611397565b5050505050505050565b6000806103e8603354610d909190611abb565b905060006103e8610d9f6112a2565b610da99190611abb565b905080610ad48386611aea565b60006109c982610a9b565b600060029054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3891906119d4565b6001600160a01b0316336001600160a01b031614610e685760405162461bcd60e51b8152600401610410906119f1565b600154198119600154191614610ee65760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610410565b600181905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c9060200161073e565b60645460408051918252602082018490527ff97ed4e083acac67830025ecbc756d8fe847cdbdca4cee3fe1e128e98b54ecb5910160405180910390a160655460408051918252602082018390527f6ab181e0440bfbf4bacdf2e99674735ce6638005490688c5f994f5399353e452910160405180910390a18082111561101f5760405162461bcd60e51b815260206004820152604b60248201527f53747261746567794261736554564c4c696d6974732e5f73657454564c4c696d60448201527f6974733a206d61785065724465706f7369742065786365656473206d6178546f60648201526a74616c4465706f7369747360a81b608482015260a401610410565b606491909155606555565b600054610100900460ff166110955760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610410565b603280546001600160a01b0319166001600160a01b0384161790556106018160006113ab565b6001600160a01b0381166111495760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610410565b600054604080516001600160a01b03620100009093048316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b60645481111561122a5760405162461bcd60e51b815260206004820152602f60248201527f53747261746567794261736554564c4c696d6974733a206d617820706572206460448201526e195c1bdcda5d08195e18d959591959608a1b6064820152608401610410565b6065546112356112a2565b11156112985760405162461bcd60e51b815260206004820152602c60248201527f53747261746567794261736554564c4c696d6974733a206d6178206465706f7360448201526b1a5d1cc8195e18d95959195960a21b6064820152608401610410565b6106018282611497565b6032546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156112eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130f9190611b2b565b905090565b6032546001600160a01b038381169116146109b65760405162461bcd60e51b815260206004820152603b60248201527f5374726174656779426173652e77697468647261773a2043616e206f6e6c792060448201527f77697468647261772074686520737472617465677920746f6b656e00000000006064820152608401610410565b6109b66001600160a01b0383168483611513565b6000546201000090046001600160a01b03161580156113d257506001600160a01b03821615155b6114545760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610410565b600181905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2610601826110bb565b6032546001600160a01b038381169116146106015760405162461bcd60e51b815260206004820152603660248201527f5374726174656779426173652e6465706f7369743a2043616e206f6e6c79206460448201527532b837b9b4ba103ab73232b9363cb4b733aa37b5b2b760511b6064820152608401610410565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092018352602080830180516001600160e01b031663a9059cbb60e01b17905283518085019094528084527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908401526109b6928692916000916115a3918516908490611620565b8051909150156109b657808060200190518101906115c19190611a3b565b6109b65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610410565b606061162f8484600085611639565b90505b9392505050565b60608247101561169a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610410565b6001600160a01b0385163b6116f15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610410565b600080866001600160a01b0316858760405161170d9190611b44565b60006040518083038185875af1925050503d806000811461174a576040519150601f19603f3d011682016040523d82523d6000602084013e61174f565b606091505b509150915061175f82828661176a565b979650505050505050565b60608315611779575081611632565b8251156117895782518084602001fd5b8160405162461bcd60e51b81526004016104109190611912565b6001600160a01b038116811461054d57600080fd5b600080600080608085870312156117ce57600080fd5b843593506020850135925060408501356117e7816117a3565b915060608501356117f7816117a3565b939692955090935050565b60006020828403121561181457600080fd5b8135611632816117a3565b6000806040838503121561183257600080fd5b50508035926020909101359150565b60006020828403121561185357600080fd5b5035919050565b6000806040838503121561186d57600080fd5b8235611878816117a3565b946020939093013593505050565b6000806040838503121561189957600080fd5b82356118a4816117a3565b915060208301356118b4816117a3565b809150509250929050565b6000602082840312156118d157600080fd5b813560ff8116811461163257600080fd5b60005b838110156118fd5781810151838201526020016118e5565b8381111561190c576000848401525b50505050565b60208152600082518060208401526119318160408501602087016118e2565b601f01601f19169190910160400192915050565b60008060006060848603121561195a57600080fd5b8335611965816117a3565b92506020840135611975816117a3565b929592945050506040919091013590565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6000602082840312156119e657600080fd5b8151611632816117a3565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215611a4d57600080fd5b8151801515811461163257600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008219821115611ace57611ace611aa5565b500190565b600082821015611ae557611ae5611aa5565b500390565b6000816000190483118215151615611b0457611b04611aa5565b500290565b600082611b2657634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215611b3d57600080fd5b5051919050565b60008251611b568184602087016118e2565b919091019291505056fe4261736520537472617465677920696d706c656d656e746174696f6e20746f20696e68657269742066726f6d20666f72206d6f726520636f6d706c657820696d706c656d656e746174696f6e73a26469706673582212208ddbf91c8cfff76479472e68dced3c207cb0d0d222e73191eea06f7ba2232d5964736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x4e59b44847b379578588920ca78fbf26c0b4956c":{"nonce":0,"balance":"0x0","code":"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3","storage":{}},"0x5fbdb2315678afecb367f032d93f642f64180aa3":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461011157806399a88ec414610124578063f2fde38b14610144578063f3b7dead1461016457600080fd5b8063204e1c7a14610080578063715018a6146100bc5780637eff275e146100d35780638da5cb5b146100f3575b600080fd5b34801561008c57600080fd5b506100a061009b366004610499565b610184565b6040516001600160a01b03909116815260200160405180910390f35b3480156100c857600080fd5b506100d1610215565b005b3480156100df57600080fd5b506100d16100ee3660046104bd565b610229565b3480156100ff57600080fd5b506000546001600160a01b03166100a0565b6100d161011f36600461050c565b610291565b34801561013057600080fd5b506100d161013f3660046104bd565b610300565b34801561015057600080fd5b506100d161015f366004610499565b610336565b34801561017057600080fd5b506100a061017f366004610499565b6103b4565b6000806000836001600160a01b03166040516101aa90635c60da1b60e01b815260040190565b600060405180830381855afa9150503d80600081146101e5576040519150601f19603f3d011682016040523d82523d6000602084013e6101ea565b606091505b5091509150816101f957600080fd5b8080602001905181019061020d91906105e2565b949350505050565b61021d6103da565b6102276000610434565b565b6102316103da565b6040516308f2839760e41b81526001600160a01b038281166004830152831690638f283970906024015b600060405180830381600087803b15801561027557600080fd5b505af1158015610289573d6000803e3d6000fd5b505050505050565b6102996103da565b60405163278f794360e11b81526001600160a01b03841690634f1ef2869034906102c990869086906004016105ff565b6000604051808303818588803b1580156102e257600080fd5b505af11580156102f6573d6000803e3d6000fd5b5050505050505050565b6103086103da565b604051631b2ce7f360e11b81526001600160a01b038281166004830152831690633659cfe69060240161025b565b61033e6103da565b6001600160a01b0381166103a85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b6103b181610434565b50565b6000806000836001600160a01b03166040516101aa906303e1469160e61b815260040190565b6000546001600160a01b031633146102275760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161039f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146103b157600080fd5b6000602082840312156104ab57600080fd5b81356104b681610484565b9392505050565b600080604083850312156104d057600080fd5b82356104db81610484565b915060208301356104eb81610484565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561052157600080fd5b833561052c81610484565b9250602084013561053c81610484565b9150604084013567ffffffffffffffff8082111561055957600080fd5b818601915086601f83011261056d57600080fd5b81358181111561057f5761057f6104f6565b604051601f8201601f19908116603f011681019083821181831017156105a7576105a76104f6565b816040528281528960208487010111156105c057600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000602082840312156105f457600080fd5b81516104b681610484565b60018060a01b038316815260006020604081840152835180604085015260005b8181101561063b5785810183015185820160600152820161061f565b8181111561064d576000606083870101525b50601f01601f19169290920160600194935050505056fea26469706673582212200fdbd2e25973eab45d03ab46d4fda931522c5b45bccd7b63ecf3c38942f8913564736f6c634300080c0033","storage":{"0x0":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"}},"0x5fc8d32690cc91d4c39d9d3abcbd16989f875707":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033","storage":{"0x0":"0x1","0x33":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x65":"0xe7f1725e7734ce288f8367e1bb143e90bb3f0512","0x66":"0x0","0x97":"0x5bc5b424ff8db9bd8202cae3beb193c946b905d8ebddb990e36a723af40eb1c4","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0xdcd1bf9a1b36ce34237eeafef220932846bcd82","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0x610178da211fef7d417bc0e6fed39f05609ad788":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106100575760003560e01c80633659cfe61461005c5780635c60da1b14610071578063715018a61461009a5780638da5cb5b146100a2578063f2fde38b146100b3575b600080fd5b61006f61006a3660046102ee565b6100c6565b005b6001546001600160a01b03165b6040516001600160a01b03909116815260200160405180910390f35b61006f61010e565b6000546001600160a01b031661007e565b61006f6100c13660046102ee565b610122565b6100ce6101af565b6100d781610209565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6101166101af565b610120600061029e565b565b61012a6101af565b6001600160a01b0381166101945760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61019d8161029e565b50565b6001600160a01b03163b151590565b6000546001600160a01b031633146101205760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161018b565b6001600160a01b0381163b61027c5760405162461bcd60e51b815260206004820152603360248201527f5570677261646561626c65426561636f6e3a20696d706c656d656e746174696f6044820152721b881a5cc81b9bdd08184818dbdb9d1c9858dd606a1b606482015260840161018b565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561030057600080fd5b81356001600160a01b038116811461031757600080fd5b939250505056fea2646970667358221220a22223d3e2a2d861ad54e68b7bc44b4d82a5a12a0bcca5c3404502bb1b430c5c64736f6c634300080c0033","storage":{"0x0":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x1":"0x8a791620dd6260079bf849dc5567adc3f2fdc318"}},"0x70997970c51812dc3a010c7d01b50e0d17dc79c8":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x8a791620dd6260079bf849dc5567adc3f2fdc318":{"nonce":1,"balance":"0x0","code":"0x6080604052600436106101855760003560e01c806374cdd798116100d1578063c49074421161008a578063e251ef5211610064578063e251ef5214610563578063e2c8344514610583578063f2882461146105a3578063fe80b087146105d757600080fd5b8063c490744214610503578063c4d66de814610523578063dda3346c1461054357600080fd5b806374cdd7981461044057806387e0d289146104745780639b4e46341461049b578063a50600f4146104ae578063b522538a146104ce578063baa7145a146104ee57600080fd5b806334bea20a1161013e57806358eaee791161011857806358eaee791461038f5780635d3f65b6146103bc5780636fcd0e53146103dc5780637439841f1461040957600080fd5b806334bea20a146103005780633f65cf191461033b5780634665bcda1461035b57600080fd5b80630b18ff66146101db5780630cd4649e146102185780631a5057be1461022f5780631d905d5c146102635780633106ab53146102af5780633474aa16146102e057600080fd5b366101d657346037600082825461019c9190614b56565b90915550506040513481527f6fdd3dbdb173299608c0aa9f368735857c8842b581f8389238bf05bd04b3bf499060200160405180910390a1005b600080fd5b3480156101e757600080fd5b506033546101fb906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561022457600080fd5b5061022d6105fb565b005b34801561023b57600080fd5b506101fb7f0000000000000000000000002279b7a0a67db372996a5fab50d91eaa73d2ebe681565b34801561026f57600080fd5b506102977f000000000000000000000000000000000000000000000000000000077359400081565b6040516001600160401b03909116815260200161020f565b3480156102bb57600080fd5b506034546102d090600160401b900460ff1681565b604051901515815260200161020f565b3480156102ec57600080fd5b50603454610297906001600160401b031681565b34801561030c57600080fd5b506102d061031b366004614b93565b603560209081526000928352604080842090915290825290205460ff1681565b34801561034757600080fd5b5061022d610356366004614c26565b610764565b34801561036757600080fd5b506101fb7f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85381565b34801561039b57600080fd5b506103af6103aa366004614d37565b610c06565b60405161020f9190614db0565b3480156103c857600080fd5b50603854610297906001600160401b031681565b3480156103e857600080fd5b506103fc6103f7366004614dbe565b610c6b565b60405161020f9190614dd7565b34801561041557600080fd5b506103af610424366004614dbe565b600090815260366020526040902054600160c01b900460ff1690565b34801561044c57600080fd5b506101fb7f00000000000000000000000000000000219ab540356cbb839cbe05303d7705fa81565b34801561048057600080fd5b5060335461029790600160a01b90046001600160401b031681565b61022d6104a9366004614e1f565b610d18565b3480156104ba57600080fd5b5061022d6104c9366004614e92565b610ec5565b3480156104da57600080fd5b506103fc6104e9366004614d37565b611294565b3480156104fa57600080fd5b5061022d611387565b34801561050f57600080fd5b5061022d61051e366004614f3c565b6113f2565b34801561052f57600080fd5b5061022d61053e366004614f68565b61162f565b34801561054f57600080fd5b5061022d61055e366004615082565b611807565b34801561056f57600080fd5b5061022d61057e366004615153565b6119da565b34801561058f57600080fd5b5061022d61059e366004614f3c565b611da5565b3480156105af57600080fd5b506102977f000000000000000000000000000000000000000000000000000000006059f46081565b3480156105e357600080fd5b506105ed60375481565b60405190815260200161020f565b604051635ac86ab760e01b8152600260048201819052907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031690635ac86ab790602401602060405180830381865afa158015610663573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610687919061524e565b156106ad5760405162461bcd60e51b81526004016106a490615270565b60405180910390fd5b6033546001600160a01b031633146106d75760405162461bcd60e51b81526004016106a4906152cd565b603454600160401b900460ff16156107015760405162461bcd60e51b81526004016106a490615315565b6034805460ff60401b1916600160401b179055603354610729906001600160a01b0316611f88565b6033546040516001600160a01b03909116907fca8dfc8c5e0a67a74501c072a3325f685259bebbae7cfd230ab85198a78b70cd90600090a250565b6033546001600160a01b0316331461078e5760405162461bcd60e51b81526004016106a4906152cd565b604051635ac86ab760e01b8152600260048201819052907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031690635ac86ab790602401602060405180830381865afa1580156107f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081a919061524e565b156108375760405162461bcd60e51b81526004016106a490615270565b60335489906001600160401b03600160a01b9091048116908216101561086f5760405162461bcd60e51b81526004016106a490615364565b603454600160401b900460ff166108e75760405162461bcd60e51b815260206004820152603660248201527f456967656e506f642e686173456e61626c656452657374616b696e673a2072656044820152751cdd185ada5b99c81a5cc81b9bdd08195b98589b195960521b60648201526084016106a4565b86851480156108f557508483145b6109855760405162461bcd60e51b815260206004820152605560248201527f456967656e506f642e7665726966795769746864726177616c43726564656e7460448201527f69616c733a2076616c696461746f72496e646963657320616e642070726f6f666064820152740e640daeae6e840c4ca40e6c2daca40d8cadccee8d605b1b608482015260a4016106a4565b4261099b613f486001600160401b038d16614b56565b1015610a245760405162461bcd60e51b815260206004820152604c60248201527f456967656e506f642e7665726966795769746864726177616c43726564656e7460448201527f69616c733a207370656369666965642074696d657374616d7020697320746f6f60648201526b0819985c881a5b881c185cdd60a21b608482015260a4016106a4565b60405163d1c64cc960e01b81526001600160401b038b166004820152610acd907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b03169063d1c64cc990602401602060405180830381865afa158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab991906153f7565b8a35610ac860208d018d615410565b611fbc565b6000805b88811015610b7157610b538c8c358c8c85818110610af157610af1615456565b9050602002016020810190610b06919061546c565b8b8b86818110610b1857610b18615456565b9050602002810190610b2a9190615410565b8b8b88818110610b3c57610b3c615456565b9050602002810190610b4e9190615493565b61214a565b610b5d9083614b56565b915080610b69816154dc565b915050610ad1565b5060335460405163030b147160e61b81526001600160a01b039182166004820152602481018390527f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8539091169063c2c51c4090604401600060405180830381600087803b158015610be157600080fd5b505af1158015610bf5573d6000803e3d6000fd5b505050505050505050505050505050565b600080610c4884848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061260492505050565b600090815260366020526040902054600160c01b900460ff169150505b92915050565b610c936040805160808101825260008082526020820181905291810182905290606082015290565b600082815260366020908152604091829020825160808101845281546001600160401b038082168352600160401b8204811694830194909452600160801b810490931693810193909352906060830190600160c01b900460ff166002811115610cfe57610cfe614d78565b6002811115610d0f57610d0f614d78565b90525092915050565b336001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8531614610d605760405162461bcd60e51b81526004016106a4906154f7565b346801bc16d674ec80000014610dec5760405162461bcd60e51b8152602060048201526044602482018190527f456967656e506f642e7374616b653a206d75737420696e697469616c6c792073908201527f74616b6520666f7220616e792076616c696461746f72207769746820333220656064820152633a3432b960e11b608482015260a4016106a4565b7f00000000000000000000000000000000219ab540356cbb839cbe05303d7705fa6001600160a01b031663228951186801bc16d674ec8000008787610e2f6126fe565b8888886040518863ffffffff1660e01b8152600401610e53969594939291906155c9565b6000604051808303818588803b158015610e6c57600080fd5b505af1158015610e80573d6000803e3d6000fd5b50505050507f606865b7934a25d4aed43f6cdb426403353fa4b3009c4d228407474581b01e238585604051610eb6929190615618565b60405180910390a15050505050565b604051635ac86ab760e01b8152600360048201819052907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031690635ac86ab790602401602060405180830381865afa158015610f2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f51919061524e565b15610f6e5760405162461bcd60e51b81526004016106a490615270565b8684148015610f7c57508382145b6110055760405162461bcd60e51b815260206004820152604e60248201527f456967656e506f642e76657269667942616c616e6365557064617465733a207660448201527f616c696461746f72496e646963657320616e642070726f6f6673206d7573742060648201526d0c4ca40e6c2daca40d8cadccee8d60931b608482015260a4016106a4565b4261101b613f486001600160401b038c16614b56565b101561109d5760405162461bcd60e51b815260206004820152604560248201527f456967656e506f642e76657269667942616c616e6365557064617465733a207360448201527f70656369666965642074696d657374616d7020697320746f6f2066617220696e606482015264081c185cdd60da1b608482015260a4016106a4565b60405163d1c64cc960e01b81526001600160401b038a166004820152611141907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b03169063d1c64cc990602401602060405180830381865afa15801561110e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113291906153f7565b8735610ac860208a018a615410565b6000805b888110156111e5576111c78b8b8b8481811061116357611163615456565b9050602002016020810190611178919061546c565b8a358a8a8681811061118c5761118c615456565b905060200281019061119e9190615410565b8a8a888181106111b0576111b0615456565b90506020028101906111c29190615493565b612743565b6111d1908361562c565b9150806111dd816154dc565b915050611145565b506033546001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85381169163c2c51c40911661122a633b9aca008561566d565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561127057600080fd5b505af1158015611284573d6000803e3d6000fd5b5050505050505050505050505050565b6112bc6040805160808101825260008082526020820181905291810182905290606082015290565b603660006112ff85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061260492505050565b81526020808201929092526040908101600020815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b81049094169281019290925290916060830190600160c01b900460ff16600281111561136c5761136c614d78565b600281111561137d5761137d614d78565b9052509392505050565b6033546001600160a01b031633146113b15760405162461bcd60e51b81526004016106a4906152cd565b603454600160401b900460ff16156113db5760405162461bcd60e51b81526004016106a490615315565b6033546113f0906001600160a01b0316611f88565b565b336001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c853161461143a5760405162461bcd60e51b81526004016106a4906154f7565b611448633b9aca0082615708565b156114d25760405162461bcd60e51b815260206004820152604e60248201527f456967656e506f642e776974686472617752657374616b6564426561636f6e4360448201527f6861696e4554483a20616d6f756e74576569206d75737420626520612077686f60648201526d1b194811ddd95a48185b5bdd5b9d60921b608482015260a4016106a4565b60006114e2633b9aca008361571c565b6034549091506001600160401b03908116908216111561159b5760405162461bcd60e51b815260206004820152606260248201527f456967656e506f642e776974686472617752657374616b6564426561636f6e4360448201527f6861696e4554483a20616d6f756e74477765692065786365656473207769746860648201527f6472617761626c6552657374616b6564457865637574696f6e4c617965724777608482015261656960f01b60a482015260c4016106a4565b603480548291906000906115b99084906001600160401b0316615730565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550826001600160a01b03167f8947fd2ce07ef9cc302c4e8f0461015615d91ce851564839e91cc804c2f49d8e8360405161161891815260200190565b60405180910390a261162a8383612c21565b505050565b600054610100900460ff161580801561164f5750600054600160ff909116105b806116695750303b158015611669575060005460ff166001145b6116cc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106a4565b6000805460ff1916600117905580156116ef576000805461ff0019166101001790555b6001600160a01b0382166117625760405162461bcd60e51b815260206004820152603460248201527f456967656e506f642e696e697469616c697a653a20706f644f776e65722063616044820152736e6e6f74206265207a65726f206164647265737360601b60648201526084016106a4565b603380546001600160a01b0384166001600160a01b031990911681179091556034805460ff60401b1916600160401b1790556040517fca8dfc8c5e0a67a74501c072a3325f685259bebbae7cfd230ab85198a78b70cd90600090a28015611803576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6033546001600160a01b031633146118315760405162461bcd60e51b81526004016106a4906152cd565b604051635ac86ab760e01b8152600560048201819052907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031690635ac86ab790602401602060405180830381865afa158015611899573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118bd919061524e565b156118da5760405162461bcd60e51b81526004016106a490615270565b82518451146119655760405162461bcd60e51b815260206004820152604b60248201527f456967656e506f642e7265636f766572546f6b656e733a20746f6b656e4c697360448201527f7420616e6420616d6f756e7473546f5769746864726177206d7573742062652060648201526a0e6c2daca40d8cadccee8d60ab1b608482015260a4016106a4565b60005b84518110156119d3576119c18385838151811061198757611987615456565b60200260200101518784815181106119a1576119a1615456565b60200260200101516001600160a01b0316612c2b9092919063ffffffff16565b806119cb816154dc565b915050611968565b5050505050565b604051635ac86ab760e01b81526004808201819052907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031690635ac86ab790602401602060405180830381865afa158015611a41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a65919061524e565b15611a825760405162461bcd60e51b81526004016106a490615270565b8386148015611a9057508588145b8015611a9b57508782145b611b0f576040805162461bcd60e51b81526020600482015260248101919091527f456967656e506f642e766572696679416e6450726f636573735769746864726160448201527f77616c733a20696e70757473206d7573742062652073616d65206c656e67746860648201526084016106a4565b60405163d1c64cc960e01b81526001600160401b038c166004820152611bb3907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b03169063d1c64cc990602401602060405180830381865afa158015611b80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba491906153f7565b8b35610ac860208e018e615410565b604080518082019091526000808252602082015260005b83811015611cb3576000611c6e8d358d8d85818110611beb57611beb615456565b9050602002810190611bfd9190615758565b8c8c86818110611c0f57611c0f615456565b9050602002810190611c219190615410565b8c8c88818110611c3357611c33615456565b9050602002810190611c459190615493565b8c8c8a818110611c5757611c57615456565b9050602002810190611c699190615493565b612c7d565b80518451919250908490611c83908390614b56565b9052506020808201519084018051611c9c90839061562c565b905250819050611cab816154dc565b915050611bca565b50805115611ce2576033548151611ce2916001600160a01b031690611cdd90633b9aca0090615779565b613169565b602081015115611d975760335460208201516001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85381169263c2c51c4092911690611d3890633b9aca009061566d565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611d7e57600080fd5b505af1158015611d92573d6000803e3d6000fd5b505050505b505050505050505050505050565b6033546001600160a01b03163314611dcf5760405162461bcd60e51b81526004016106a4906152cd565b604051635ac86ab760e01b8152600560048201819052907f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031690635ac86ab790602401602060405180830381865afa158015611e37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5b919061524e565b15611e785760405162461bcd60e51b81526004016106a490615270565b603754821115611f295760405162461bcd60e51b815260206004820152606a60248201527f456967656e506f642e77697468647261776e6f6e426561636f6e436861696e4560448201527f544842616c616e63655765693a20616d6f756e74546f5769746864726177206960648201527f732067726561746572207468616e206e6f6e426561636f6e436861696e45544860848201526942616c616e636557656960b01b60a482015260c4016106a4565b8160376000828254611f3b9190615798565b90915550506040518281526001600160a01b038416907f30420aacd028abb3c1fd03aba253ae725d6ddd52d16c9ac4cb5742cd43f530969060200160405180910390a261162a8383613169565b6033805467ffffffffffffffff60a01b19164263ffffffff16600160a01b021790556000603755611fb98147613169565b50565b611fc860036020615779565b81146120585760405162461bcd60e51b815260206004820152605360248201527f426561636f6e436861696e50726f6f66732e7665726966795374617465526f6f60448201527f74416761696e73744c6174657374426c6f636b526f6f743a2050726f6f6620686064820152720c2e640d2dcc6dee4e4cac6e840d8cadccee8d606b1b608482015260a4016106a4565b61209d82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250879150600390506131f7565b6121445760405162461bcd60e51b815260206004820152606660248201527f426561636f6e436861696e50726f6f66732e7665726966795374617465526f6f60448201527f74416761696e73744c6174657374426c6f636b526f6f743a20496e76616c696460648201527f206c617465737420626c6f636b2068656164657220726f6f74206d65726b6c6560848201526510383937b7b360d11b60a482015260c4016106a4565b50505050565b60008061218984848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061320f92505050565b6000818152603660209081526040808320815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b8104909416928101929092529394509192906060830190600160c01b900460ff1660028111156121f8576121f8614d78565b600281111561220957612209614d78565b905250905060008160600151600281111561222657612226614d78565b146122cf5760405162461bcd60e51b815260206004820152606760248201527f456967656e506f642e766572696679436f72726563745769746864726177616c60448201527f43726564656e7469616c733a2056616c696461746f72206d757374206265206960648201527f6e61637469766520746f2070726f7665207769746864726177616c2063726564608482015266656e7469616c7360c81b60a482015260c4016106a4565b6122d76126fe565b6122e0906157af565b61231c86868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061323392505050565b146123a35760405162461bcd60e51b815260206004820152604b60248201527f456967656e506f642e766572696679436f72726563745769746864726177616c60448201527f43726564656e7469616c733a2050726f6f66206973206e6f7420666f7220746860648201526a1a5cc8115a59d95b941bd960aa1b608482015260a4016106a4565b60006123e186868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061324892505050565b90506123f18a87878b8b8e61326d565b60398054906000612401836154dc565b90915550506001606083015264ffffffffff891682526001600160401b038b811660408401527f000000000000000000000000000000000000000000000000000000077359400081169082161115612487576001600160401b037f0000000000000000000000000000000000000000000000000000000773594000166020830152612497565b6001600160401b03811660208301525b6000838152603660209081526040918290208451815492860151938601516001600160401b03908116600160801b0267ffffffffffffffff60801b19958216600160401b026001600160801b0319909516919092161792909217928316821781556060850151859391929091839160ff60c01b191668ffffffffffffffffff60801b1990911617600160c01b83600281111561253557612535614d78565b02179055505060405164ffffffffff8b1681527f2d0800bbc377ea54a08c5db6a87aafff5e3e9c8fead0eda110e40e0c10441449915060200160405180910390a17f0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df898c84602001516040516125d09392919064ffffffffff9390931683526001600160401b03918216602084015216604082015260600190565b60405180910390a1633b9aca0082602001516001600160401b03166125f59190615779565b9b9a5050505050505050505050565b6000815160301461268d5760405162461bcd60e51b815260206004820152604760248201527f456967656e506f642e5f63616c63756c61746556616c696461746f725075626b60448201527f657948617368206d75737420626520612034382d6279746520424c53207075626064820152666c6963206b657960c81b608482015260a4016106a4565b6040516002906126a49084906000906020016157d3565b60408051601f19818403018152908290526126be91615802565b602060405180830381855afa1580156126db573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610c6591906153f7565b60408051600160f81b60208201526000602182015230606090811b6bffffffffffffffffffffffff1916602c8301529101604051602081830303815290604052905090565b60008061278284848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061324892505050565b905060006127c285858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061320f92505050565b6000818152603660209081526040808320815160808101835281546001600160401b038082168352600160401b8204811695830195909552600160801b8104909416928101929092529394509192906060830190600160c01b900460ff16600281111561283157612831614d78565b600281111561284257612842614d78565b8152505090508a6001600160401b031681604001516001600160401b0316106128f95760405162461bcd60e51b815260206004820152605c60248201527f456967656e506f642e76657269667942616c616e63655570646174653a20566160448201527f6c696461746f72732062616c616e63652068617320616c72656164792062656560648201527f6e207570646174656420666f7220746869732074696d657374616d7000000000608482015260a4016106a4565b60018160600151600281111561291157612911614d78565b146129795760405162461bcd60e51b815260206004820152603260248201527f456967656e506f642e76657269667942616c616e63655570646174653a2056616044820152716c696461746f72206e6f742061637469766560701b60648201526084016106a4565b6129828b6134c4565b6001600160401b03166129c78787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506135ae92505050565b6001600160401b031611612a6a576000836001600160401b031611612a6a5760405162461bcd60e51b815260206004820152604d60248201527f456967656e506f642e76657269667942616c616e63655570646174653a20766160448201527f6c696461746f7220697320776974686472617761626c6520627574206861732060648201526c3737ba103bb4ba34323930bbb760991b608482015260a4016106a4565b612a788987878b8b8f61326d565b602081015160006001600160401b037f000000000000000000000000000000000000000000000000000000077359400081169086161115612ada57507f0000000000000000000000000000000000000000000000000000000773594000612add565b50835b6001600160401b0380821660208086019182528f831660408088019182526000898152603690935290912086518154935192518516600160801b0267ffffffffffffffff60801b19938616600160401b026001600160801b031990951691909516179290921790811683178255606086015186939091839160ff60c01b191668ffffffffffffffffff60801b1990911617600160c01b836002811115612b8557612b85614d78565b0217905550905050816001600160401b0316816001600160401b031614612c11577f0e5fac175b83177cc047381e030d8fb3b42b37bd1c025e22c280facad62c32df8c8e83604051612bfc9392919064ffffffffff9390931683526001600160401b03918216602084015216604082015260600190565b60405180910390a1612c0e81836135c6565b95505b5050505050979650505050505050565b61180382826135e5565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261162a9084906136fe565b6040805180820190915260008082526020820152612ca2612c9d89615883565b6137d0565b6033546001600160401b03600160a01b90910481169082161015612cd85760405162461bcd60e51b81526004016106a490615364565b6000612ce6612c9d8b615883565b90506000612d2688888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061320f92505050565b905060008082815260366020526040902054600160c01b900460ff166002811115612d5357612d53614d78565b1415612e0a5760405162461bcd60e51b815260206004820152607460248201527f456967656e506f642e5f766572696679416e6450726f6365737357697468647260448201527f6177616c3a2056616c696461746f72206e657665722070726f76656e20746f2060648201527f68617665207769746864726177616c2063726564656e7469616c7320706f696e6084820152731d1959081d1bc81d1a1a5cc818dbdb9d1c9858dd60621b60a482015260c4016106a4565b60008181526035602090815260408083206001600160401b038616845290915290205460ff1615612ec95760405162461bcd60e51b815260206004820152605b60248201527f456967656e506f642e5f766572696679416e6450726f6365737357697468647260448201527f6177616c3a207769746864726177616c2068617320616c72656164792062656560648201527f6e2070726f76656e20666f7220746869732074696d657374616d700000000000608482015260a4016106a4565b6001603560008381526020019081526020016000206000846001600160401b03166001600160401b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550612fa68c87878e7f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b03166344e71c806040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fa191906159bf565b6137e0565b6000612fe487878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061420192505050565b9050612ff48d8a8a8e8e8661326d565b600061303288888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061421992505050565b90506130708a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506135ae92505050565b6001600160401b031661308a6130858f615883565b614231565b6001600160401b03161061314257603354600084815260366020908152604091829020825160808101845281546001600160401b038082168352600160401b8204811694830194909452600160801b81049093169381019390935261313793869388938a936001600160a01b03909316928892916060830190600160c01b900460ff16600281111561311e5761311e614d78565b600281111561312f5761312f614d78565b905250614243565b95505050505061315c565b60335461313790839086906001600160a01b031684614481565b5098975050505050505050565b603354604051633036cd5360e21b81526001600160a01b03918216600482015283821660248201527f0000000000000000000000002279b7a0a67db372996a5fab50d91eaa73d2ebe69091169063c0db354c9083906044016000604051808303818588803b1580156131da57600080fd5b505af11580156131ee573d6000803e3d6000fd5b50505050505050565b60008361320586858561455f565b1495945050505050565b60008160008151811061322457613224615456565b60200260200101519050919050565b60008160018151811061322457613224615456565b6000610c658260028151811061326057613260615456565b60200260200101516146ab565b61327960036002615ac0565b84146133045760405162461bcd60e51b815260206004820152604e60248201527f426561636f6e436861696e50726f6f66732e76657269667956616c696461746f60448201527f724669656c64733a2056616c696461746f72206669656c64732068617320696e60648201526d0c6dee4e4cac6e840d8cadccee8d60931b608482015260a4016106a4565b600561331260286001614b56565b61331c9190614b56565b613327906020615779565b82146133a75760405162461bcd60e51b815260206004820152604360248201527f426561636f6e436861696e50726f6f66732e76657269667956616c696461746f60448201527f724669656c64733a2050726f6f662068617320696e636f7272656374206c656e6064820152620cee8d60eb1b608482015260a4016106a4565b600064ffffffffff82166133bd60286001614b56565b600b901b179050600061340287878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061471292505050565b905061344885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508591508690506131f7565b6134ba5760405162461bcd60e51b815260206004820152603d60248201527f426561636f6e436861696e50726f6f66732e76657269667956616c696461746f60448201527f724669656c64733a20496e76616c6964206d65726b6c652070726f6f6600000060648201526084016106a4565b5050505050505050565b60007f000000000000000000000000000000000000000000000000000000006059f4606001600160401b0316826001600160401b0316101561356e5760405162461bcd60e51b815260206004820152603760248201527f456967656e506f642e5f74696d657374616d70546f45706f63683a2074696d6560448201527f7374616d70206973206265666f72652067656e6573697300000000000000000060648201526084016106a4565b61357a600c6020615acc565b6135a47f000000000000000000000000000000000000000000000000000000006059f46084615730565b610c659190615afb565b6000610c658260078151811061326057613260615456565b60006135de6001600160401b03808416908516615b21565b9392505050565b804710156136355760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016106a4565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613682576040519150601f19603f3d011682016040523d82523d6000602084013e613687565b606091505b505090508061162a5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016106a4565b6000613753826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166149bf9092919063ffffffff16565b80519091501561162a5780806020019051810190613771919061524e565b61162a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016106a4565b6000610c658261014001516146ab565b6137eb600280615ac0565b831461385f5760405162461bcd60e51b81526020600482015260496024820152600080516020615bd383398151915260448201527f616c3a207769746864726177616c4669656c64732068617320696e636f7272656064820152680c6e840d8cadccee8d60bb1b608482015260a4016106a4565b61386b600d6002615ac0565b61387b60c0840160a08501615b60565b6001600160401b0316106138e55760405162461bcd60e51b815260206004820152603f6024820152600080516020615bd383398151915260448201527f616c3a20626c6f636b526f6f74496e64657820697320746f6f206c617267650060648201526084016106a4565b6138f160046002615ac0565b613902610100840160e08501615b60565b6001600160401b03161061396e576040805162461bcd60e51b8152602060048201526024810191909152600080516020615bd383398151915260448201527f616c3a207769746864726177616c496e64657820697320746f6f206c6172676560648201526084016106a4565b61397a60186002615ac0565b61398a60e0840160c08501615b60565b6001600160401b031610613a045760405162461bcd60e51b81526020600482015260476024820152600080516020615bd383398151915260448201527f616c3a20686973746f726963616c53756d6d617279496e64657820697320746f6064820152666f206c6172676560c81b608482015260a4016106a4565b60006001600160401b038216613a1c612c9d85615883565b6001600160401b031610613a31576005613a34565b60045b9050613a41600482614b56565b613a4c906001614b56565b613a57906020615779565b613a618480615410565b905014613ad55760405162461bcd60e51b81526020600482015260486024820152600080516020615bd383398151915260448201527f616c3a207769746864726177616c50726f6f662068617320696e636f727265636064820152670e840d8cadccee8d60c31b608482015260a4016106a4565b613ae160046003614b56565b613aec906020615779565b613af96040850185615410565b905014613b735760405162461bcd60e51b815260206004820152604e6024820152600080516020615bd383398151915260448201527f616c3a20657865637574696f6e5061796c6f616450726f6f662068617320696e60648201526d0c6dee4e4cac6e840d8cadccee8d60931b608482015260a4016106a4565b613b7f60036020615779565b613b8c6020850185615410565b905014613bfa5760405162461bcd60e51b81526020600482015260426024820152600080516020615bd383398151915260448201527f616c3a20736c6f7450726f6f662068617320696e636f7272656374206c656e676064820152610e8d60f31b608482015260a4016106a4565b613c05816020615779565b613c126060850185615410565b905014613c855760405162461bcd60e51b81526020600482015260476024820152600080516020615bd383398151915260448201527f616c3a2074696d657374616d7050726f6f662068617320696e636f7272656374606482015266040d8cadccee8d60cb1b608482015260a4016106a4565b600d613c9360186001614b56565b613c9e906005614b56565b613ca9906001614b56565b613cb39190614b56565b613cbe906020615779565b613ccb6080850185615410565b905014613d545760405162461bcd60e51b81526020600482015260586024820152600080516020615bd383398151915260448201527f616c3a20686973746f726963616c53756d6d617279426c6f636b526f6f74507260648201527f6f6f662068617320696e636f7272656374206c656e6774680000000000000000608482015260a4016106a4565b6000613d6660c0850160a08601615b60565b6001600160401b03166000613d7d600d6001614b56565b613d8d60e0880160c08901615b60565b6001600160401b0316901b600d613da660186001614b56565b613db1906001614b56565b613dbb9190614b56565b601b901b1717179050613e16613dd46080860186615410565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92505050610100870135846131f7565b613e895760405162461bcd60e51b815260206004820152604a6024820152600080516020615bd383398151915260448201527f616c3a20496e76616c696420686973746f726963616c73756d6d617279206d656064820152693935b63290383937b7b360b11b608482015260a4016106a4565b613ee0613e996020860186615410565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506101008a013593506101208a0135925090506131f7565b613f405760405162461bcd60e51b815260206004820152603d6024820152600080516020615bd383398151915260448201527f616c3a20496e76616c696420736c6f74206d65726b6c652070726f6f6600000060648201526084016106a4565b6049613f98613f526040870187615410565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505050610100870135610160880135846131f7565b61400a5760405162461bcd60e51b81526020600482015260496024820152600080516020615bd383398151915260448201527f616c3a20496e76616c696420657865637574696f6e5061796c6f6164206d657260648201526835b63290383937b7b360b91b608482015260a4016106a4565b5061406261401b6060860186615410565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505061016086013561014087013560096131f7565b6140cd5760405162461bcd60e51b81526020600482015260426024820152600080516020615bd383398151915260448201527f616c3a20496e76616c69642074696d657374616d70206d65726b6c652070726f60648201526137b360f11b608482015260a4016106a4565b60006140e0610100860160e08701615b60565b6001600160401b03166140f560046001614b56565b600e901b179050600061413a88888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061471292505050565b905061418a6141498780615410565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505061016088013583856131f7565b6141f65760405162461bcd60e51b81526020600482015260436024820152600080516020615bd383398151915260448201527f616c3a20496e76616c6964207769746864726177616c206d65726b6c6520707260648201526237b7b360e91b608482015260a4016106a4565b505050505050505050565b6000610c658260018151811061326057613260615456565b6000610c658260038151811061326057613260615456565b600060206135a48361012001516146ab565b604080518082019091526000808252602082015260007f00000000000000000000000000000000000000000000000000000007735940006001600160401b0316846001600160401b031611156142ba57507f00000000000000000000000000000000000000000000000000000007735940006142bd565b50825b60408051808201909152600080825260208201526142db8286615730565b6001600160401b0390811682526034805484926000916142fd91859116615b7d565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555061432f8285602001516135c6565b602082015260028460600151600281111561434c5761434c614d78565b1461436e576039805490600061436183615ba8565b9091555050600260608501525b600060208086018281528a83526036909152604091829020865181549251938801516001600160401b03908116600160801b0267ffffffffffffffff60801b19958216600160401b026001600160801b0319909516929091169190911792909217928316821781556060870151879391929091839160ff60c01b191668ffffffffffffffffff60801b1990911617600160c01b83600281111561441357614413614d78565b0217905550506040805164ffffffffff8c1681526001600160401b038a8116602083015288168183015290516001600160a01b03891692507fb76a93bb649ece524688f1a01d184e0bbebcda58eae80c28a898bec3fb5a09639181900360600190a298975050505050505050565b60408051808201909152600080825260208201526040805164ffffffffff871681526001600160401b0380871660208301528416918101919091526001600160a01b038416907f8a7335714231dbd551aaba6314f4a97a14c201e53a3e25e1140325cdf67d7a4e9060600160405180910390a2603880548391906000906145129084906001600160401b0316615b7d565b92506101000a8154816001600160401b0302191690836001600160401b031602179055506040518060400160405280836001600160401b0316815260200160008152509050949350505050565b6000835160001415801561457e57506020845161457c9190615708565b155b61460d5760405162461bcd60e51b815260206004820152605460248201527f4d65726b6c652e70726f63657373496e636c7573696f6e50726f6f665368613260448201527f35363a2070726f6f66206c656e6774682073686f756c642062652061206e6f6e60648201527316bd32b9379036bab63a34b836329037b310199960611b608482015260a4016106a4565b604080516020808201909252848152905b855181116146a157614631600285615708565b614664578151600052808601516020526020826040600060026107d05a03fa61465957600080fd5b60028404935061468f565b8086015160005281516020526020826040600060026107d05a03fa61468857600080fd5b6002840493505b61469a602082614b56565b905061461e565b5051949350505050565b60f881901c60e882901c61ff00161760d882901c62ff0000161760c882901c63ff000000161764ff0000000060b883901c161765ff000000000060a883901c161766ff000000000000609883901c161767ff0000000000000060889290921c919091161790565b60008060028351614723919061571c565b90506000816001600160401b0381111561473f5761473f614f85565b604051908082528060200260200182016040528015614768578160200160208202803683370190505b50905060005b8281101561486f576002856147838383615779565b8151811061479357614793615456565b6020026020010151868360026147a99190615779565b6147b4906001614b56565b815181106147c4576147c4615456565b60200260200101516040516020016147e6929190918252602082015260400190565b60408051601f198184030181529082905261480091615802565b602060405180830381855afa15801561481d573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061484091906153f7565b82828151811061485257614852615456565b602090810291909101015280614867816154dc565b91505061476e565b5061487b60028361571c565b91505b811561499b5760005b828110156149885760028261489c8383615779565b815181106148ac576148ac615456565b6020026020010151838360026148c29190615779565b6148cd906001614b56565b815181106148dd576148dd615456565b60200260200101516040516020016148ff929190918252602082015260400190565b60408051601f198184030181529082905261491991615802565b602060405180830381855afa158015614936573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061495991906153f7565b82828151811061496b5761496b615456565b602090810291909101015280614980816154dc565b915050614887565b5061499460028361571c565b915061487e565b806000815181106149ae576149ae615456565b602002602001015192505050919050565b60606149ce84846000856149d6565b949350505050565b606082471015614a375760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016106a4565b6001600160a01b0385163b614a8e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106a4565b600080866001600160a01b03168587604051614aaa9190615802565b60006040518083038185875af1925050503d8060008114614ae7576040519150601f19603f3d011682016040523d82523d6000602084013e614aec565b606091505b5091509150614afc828286614b07565b979650505050505050565b60608315614b165750816135de565b825115614b265782518084602001fd5b8160405162461bcd60e51b81526004016106a49190615bbf565b634e487b7160e01b600052601160045260246000fd5b60008219821115614b6957614b69614b40565b500190565b6001600160401b0381168114611fb957600080fd5b8035614b8e81614b6e565b919050565b60008060408385031215614ba657600080fd5b823591506020830135614bb881614b6e565b809150509250929050565b600060408284031215614bd557600080fd5b50919050565b60008083601f840112614bed57600080fd5b5081356001600160401b03811115614c0457600080fd5b6020830191508360208260051b8501011115614c1f57600080fd5b9250929050565b60008060008060008060008060a0898b031215614c4257600080fd5b8835614c4d81614b6e565b975060208901356001600160401b0380821115614c6957600080fd5b614c758c838d01614bc3565b985060408b0135915080821115614c8b57600080fd5b614c978c838d01614bdb565b909850965060608b0135915080821115614cb057600080fd5b614cbc8c838d01614bdb565b909650945060808b0135915080821115614cd557600080fd5b50614ce28b828c01614bdb565b999c989b5096995094979396929594505050565b60008083601f840112614d0857600080fd5b5081356001600160401b03811115614d1f57600080fd5b602083019150836020828501011115614c1f57600080fd5b60008060208385031215614d4a57600080fd5b82356001600160401b03811115614d6057600080fd5b614d6c85828601614cf6565b90969095509350505050565b634e487b7160e01b600052602160045260246000fd5b60038110614dac57634e487b7160e01b600052602160045260246000fd5b9052565b60208101610c658284614d8e565b600060208284031215614dd057600080fd5b5035919050565b60006080820190506001600160401b03808451168352806020850151166020840152806040850151166040840152506060830151614e186060840182614d8e565b5092915050565b600080600080600060608688031215614e3757600080fd5b85356001600160401b0380821115614e4e57600080fd5b614e5a89838a01614cf6565b90975095506020880135915080821115614e7357600080fd5b50614e8088828901614cf6565b96999598509660400135949350505050565b60008060008060008060008060a0898b031215614eae57600080fd5b8835614eb981614b6e565b975060208901356001600160401b0380821115614ed557600080fd5b614ee18c838d01614bdb565b909950975060408b0135915080821115614efa57600080fd5b614f068c838d01614bc3565b965060608b0135915080821115614cb057600080fd5b6001600160a01b0381168114611fb957600080fd5b8035614b8e81614f1c565b60008060408385031215614f4f57600080fd5b8235614f5a81614f1c565b946020939093013593505050565b600060208284031215614f7a57600080fd5b81356135de81614f1c565b634e487b7160e01b600052604160045260246000fd5b60405161018081016001600160401b0381118282101715614fbe57614fbe614f85565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614fec57614fec614f85565b604052919050565b60006001600160401b0382111561500d5761500d614f85565b5060051b60200190565b600082601f83011261502857600080fd5b8135602061503d61503883614ff4565b614fc4565b82815260059290921b8401810191818101908684111561505c57600080fd5b8286015b848110156150775780358352918301918301615060565b509695505050505050565b60008060006060848603121561509757600080fd5b83356001600160401b03808211156150ae57600080fd5b818601915086601f8301126150c257600080fd5b813560206150d261503883614ff4565b82815260059290921b8401810191818101908a8411156150f157600080fd5b948201945b8386101561511857853561510981614f1c565b825294820194908201906150f6565b9750508701359250508082111561512e57600080fd5b5061513b86828701615017565b92505061514a60408501614f31565b90509250925092565b60008060008060008060008060008060c08b8d03121561517257600080fd5b61517b8b614b83565b995060208b01356001600160401b038082111561519757600080fd5b6151a38e838f01614bc3565b9a5060408d01359150808211156151b957600080fd5b6151c58e838f01614bdb565b909a50985060608d01359150808211156151de57600080fd5b6151ea8e838f01614bdb565b909850965060808d013591508082111561520357600080fd5b61520f8e838f01614bdb565b909650945060a08d013591508082111561522857600080fd5b506152358d828e01614bdb565b915080935050809150509295989b9194979a5092959850565b60006020828403121561526057600080fd5b815180151581146135de57600080fd5b6020808252603e908201527f456967656e506f642e6f6e6c795768656e4e6f745061757365643a20696e646560408201527f782069732070617573656420696e20456967656e506f644d616e616765720000606082015260800190565b60208082526028908201527f456967656e506f642e6f6e6c79456967656e506f644f776e65723a206e6f74206040820152673837b227bbb732b960c11b606082015260800190565b6020808252602f908201527f456967656e506f642e6861734e6576657252657374616b65643a20726573746160408201526e1ada5b99c81a5cc8195b98589b1959608a1b606082015260800190565b60208082526067908201527f456967656e506f642e70726f6f664973466f7256616c696454696d657374616d60408201527f703a20626561636f6e20636861696e2070726f6f66206d75737420626520617460608201527f206f72206166746572206d6f7374526563656e745769746864726177616c546960808201526606d657374616d760cc1b60a082015260c00190565b60006020828403121561540957600080fd5b5051919050565b6000808335601e1984360301811261542757600080fd5b8301803591506001600160401b0382111561544157600080fd5b602001915036819003821315614c1f57600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561547e57600080fd5b813564ffffffffff811681146135de57600080fd5b6000808335601e198436030181126154aa57600080fd5b8301803591506001600160401b038211156154c457600080fd5b6020019150600581901b3603821315614c1f57600080fd5b60006000198214156154f0576154f0614b40565b5060010190565b60208082526031908201527f456967656e506f642e6f6e6c79456967656e506f644d616e616765723a206e6f6040820152703a1032b4b3b2b72837b226b0b730b3b2b960791b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60005b8381101561558c578181015183820152602001615574565b838111156121445750506000910152565b600081518084526155b5816020860160208601615571565b601f01601f19169290920160200192915050565b6080815260006155dd60808301888a615548565b82810360208401526155ef818861559d565b90508281036040840152615604818688615548565b915050826060830152979650505050505050565b6020815260006149ce602083018486615548565b600080821280156001600160ff1b038490038513161561564e5761564e614b40565b600160ff1b839003841281161561566757615667614b40565b50500190565b60006001600160ff1b038184138284138082168684048611161561569357615693614b40565b600160ff1b60008712828116878305891216156156b2576156b2614b40565b600087129250878205871284841616156156ce576156ce614b40565b878505871281841616156156e4576156e4614b40565b505050929093029392505050565b634e487b7160e01b600052601260045260246000fd5b600082615717576157176156f2565b500690565b60008261572b5761572b6156f2565b500490565b60006001600160401b038381169083168181101561575057615750614b40565b039392505050565b6000823561017e1983360301811261576f57600080fd5b9190910192915050565b600081600019048311821515161561579357615793614b40565b500290565b6000828210156157aa576157aa614b40565b500390565b80516020808301519190811015614bd55760001960209190910360031b1b16919050565b600083516157e5818460208801615571565b6001600160801b0319939093169190920190815260100192915050565b6000825161576f818460208701615571565b600082601f83011261582557600080fd5b81356001600160401b0381111561583e5761583e614f85565b615851601f8201601f1916602001614fc4565b81815284602083860101111561586657600080fd5b816020850160208301376000918101602001919091529392505050565b6000610180823603121561589657600080fd5b61589e614f9b565b82356001600160401b03808211156158b557600080fd5b6158c136838701615814565b835260208501359150808211156158d757600080fd5b6158e336838701615814565b602084015260408501359150808211156158fc57600080fd5b61590836838701615814565b6040840152606085013591508082111561592157600080fd5b61592d36838701615814565b6060840152608085013591508082111561594657600080fd5b5061595336828601615814565b60808301525061596560a08401614b83565b60a082015261597660c08401614b83565b60c082015261598760e08401614b83565b60e082015261010083810135908201526101208084013590820152610140808401359082015261016092830135928101929092525090565b6000602082840312156159d157600080fd5b81516135de81614b6e565b600181815b80851115615a175781600019048211156159fd576159fd614b40565b80851615615a0a57918102915b93841c93908002906159e1565b509250929050565b600082615a2e57506001610c65565b81615a3b57506000610c65565b8160018114615a515760028114615a5b57615a77565b6001915050610c65565b60ff841115615a6c57615a6c614b40565b50506001821b610c65565b5060208310610133831016604e8410600b8410161715615a9a575081810a610c65565b615aa483836159dc565b8060001904821115615ab857615ab8614b40565b029392505050565b60006135de8383615a1f565b60006001600160401b0380831681851681830481118215151615615af257615af2614b40565b02949350505050565b60006001600160401b0380841680615b1557615b156156f2565b92169190910492915050565b60008083128015600160ff1b850184121615615b3f57615b3f614b40565b6001600160ff1b0384018313811615615b5a57615b5a614b40565b50500390565b600060208284031215615b7257600080fd5b81356135de81614b6e565b60006001600160401b03808316818516808303821115615b9f57615b9f614b40565b01949350505050565b600081615bb757615bb7614b40565b506000190190565b6020815260006135de602083018461559d56fe426561636f6e436861696e50726f6f66732e7665726966795769746864726177a264697066735822122028632f0badb0d5a48e7147a2a4a101d592d417e2a3f16ef6718f13f04f32109264736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x90f79bf6eb2c4f870365e785982e1f101e93b906":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x959922be3caee4b8cd9a407cc3ac1c251c2007b1":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061014b5760003560e01c806385594e58116100b6578063e4f4f8871161006f578063e4f4f887146103cc578063e5db06c014610405578063eb990c5914610425578063ecb7cb1b14610445578063f2fde38b14610472578063fabc1cbc1461049257600080fd5b806385594e5814610317578063886f1195146103445780638da5cb5b14610364578063c0db354c14610382578063ca661c0414610395578063d44e1b76146103ac57600080fd5b806350f73e7c1161010857806350f73e7c14610254578063595c6a67146102785780635ac86ab71461028d5780635c975abb146102cd578063715018a6146102e257806375608896146102f757600080fd5b806310d67a2f14610150578063136439dd146101725780631f39d87f146101925780633e1de008146101c85780634665bcda146101e85780634d50f9a414610234575b600080fd5b34801561015c57600080fd5b5061017061016b36600461196d565b6104b2565b005b34801561017e57600080fd5b5061017061018d366004611991565b61056e565b34801561019e57600080fd5b506101b26101ad36600461196d565b6106ad565b6040516101bf91906119c8565b60405180910390f35b3480156101d457600080fd5b506101b26101e336600461196d565b6108a8565b3480156101f457600080fd5b5061021c7f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85381565b6040516001600160a01b0390911681526020016101bf565b34801561024057600080fd5b5061017061024f366004611991565b6109ee565b34801561026057600080fd5b5061026a60c95481565b6040519081526020016101bf565b34801561028457600080fd5b506101706109ff565b34801561029957600080fd5b506102bd6102a8366004611a15565b609854600160ff9092169190911b9081161490565b60405190151581526020016101bf565b3480156102d957600080fd5b5060985461026a565b3480156102ee57600080fd5b50610170610ac6565b34801561030357600080fd5b506102bd610312366004611a38565b610ada565b34801561032357600080fd5b50610337610332366004611a38565b610b5d565b6040516101bf9190611a64565b34801561035057600080fd5b5060975461021c906001600160a01b031681565b34801561037057600080fd5b506033546001600160a01b031661021c565b610170610390366004611a72565b610bdd565b3480156103a157600080fd5b5061026a62034bc081565b3480156103b857600080fd5b506101706103c7366004611991565b610e9d565b3480156103d857600080fd5b5061026a6103e736600461196d565b6001600160a01b0316600090815260ca602052604090206001015490565b34801561041157600080fd5b50610170610420366004611a38565b610f31565b34801561043157600080fd5b50610170610440366004611aab565b610fc6565b34801561045157600080fd5b5061046561046036600461196d565b6110ee565b6040516101bf9190611af1565b34801561047e57600080fd5b5061017061048d36600461196d565b6111a8565b34801561049e57600080fd5b506101706104ad366004611991565b61121e565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610505573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105299190611b47565b6001600160a01b0316336001600160a01b0316146105625760405162461bcd60e51b815260040161055990611b64565b60405180910390fd5b61056b8161137a565b50565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156105b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105da9190611bae565b6105f65760405162461bcd60e51b815260040161055990611bd0565b6098548181161461066f5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610559565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6001600160a01b038116600090815260ca6020526040812080546001909101546060926106da8383611c2e565b90508060005b82811015610786576001600160a01b038716600090815260ca6020526040812060010161070d8388611c45565b8154811061071d5761071d611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff1691810182905260c95490925061076391611c45565b4310156107735781925050610786565b508061077e81611c73565b9150506106e0565b508060008167ffffffffffffffff8111156107a3576107a3611c8e565b6040519080825280602002602001820160405280156107e857816020015b60408051808201909152600080825260208201528152602001906001900390816107c15790505b509050811561089d5760005b8281101561089b576001600160a01b038916600090815260ca602052604090206001016108218289611c45565b8154811061083157610831611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff1691810191909152825183908390811061087d5761087d611c5d565b6020026020010181905250808061089390611c73565b9150506107f4565b505b979650505050505050565b6001600160a01b038116600090815260ca6020526040812080546001909101546060926108d58383611c2e565b905060008167ffffffffffffffff8111156108f2576108f2611c8e565b60405190808252806020026020018201604052801561093757816020015b60408051808201909152600080825260208201528152602001906001900390816109105790505b50905060005b828110156109e4576001600160a01b038716600090815260ca6020526040902060010161096a8287611c45565b8154811061097a5761097a611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff169181019190915282518390839081106109c6576109c6611c5d565b602002602001018190525080806109dc90611c73565b91505061093d565b5095945050505050565b6109f6611471565b61056b816114cb565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610a47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6b9190611bae565b610a875760405162461bcd60e51b815260040161055990611bd0565b600019609881905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b610ace611471565b610ad86000611593565b565b6001600160a01b038216600090815260ca60205260408120548210801590610b54575060c9546001600160a01b038416600090815260ca60205260409020600101805484908110610b2d57610b2d611c5d565b600091825260209091200154610b509190600160e01b900463ffffffff16611c45565b4310155b90505b92915050565b60408051808201909152600080825260208201526001600160a01b038316600090815260ca60205260409020600101805483908110610b9e57610b9e611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff16918101919091529392505050565b60405163a38406a360e01b81526001600160a01b038084166004830152839133917f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c853169063a38406a390602401602060405180830381865afa158015610c47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6b9190611b47565b6001600160a01b031614610ce75760405162461bcd60e51b815260206004820152603d60248201527f44656c617965645769746864726177616c526f757465722e6f6e6c794569676560448201527f6e506f643a206e6f7420706f644f776e6572277320456967656e506f640000006064820152608401610559565b60985460009060019081161415610d105760405162461bcd60e51b815260040161055990611ca4565b6001600160a01b038316610da65760405162461bcd60e51b815260206004820152605160248201527f44656c617965645769746864726177616c526f757465722e637265617465446560448201527f6c617965645769746864726177616c3a20726563697069656e742063616e6e6f60648201527074206265207a65726f206164647265737360781b608482015260a401610559565b346001600160e01b03811615610e96576040805180820182526001600160e01b03808416825263ffffffff43811660208085019182526001600160a01b038a16600081815260ca8352968720600190810180548083018255818a5293892088519551909616600160e01b029490961693909317939091019290925593525490917fb8f1b14c7caf74150801dcc9bc18d575cbeaf5b421943497e409df92c92e0f5991889188918691610e5791611c2e565b604080516001600160a01b0395861681529490931660208501526001600160e01b039091169183019190915260608201526080015b60405180910390a1505b5050505050565b60026065541415610ef05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610559565b600260655560985460009060019081161415610f1e5760405162461bcd60e51b815260040161055990611ca4565b610f2833836115e5565b50506001606555565b60026065541415610f845760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610559565b600260655560985460009060019081161415610fb25760405162461bcd60e51b815260040161055990611ca4565b610fbc83836115e5565b5050600160655550565b600054610100900460ff1615808015610fe65750600054600160ff909116105b806110005750303b158015611000575060005460ff166001145b6110635760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610559565b6000805460ff191660011790558015611086576000805461ff0019166101001790555b61108f85611593565b6110998484611750565b6110a2826114cb565b8015610e96576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6040805180820190915260008152606060208201526001600160a01b038216600090815260ca6020908152604080832081518083018352815481526001820180548451818702810187019095528085529195929486810194939192919084015b8282101561119a57600084815260209081902060408051808201909152908401546001600160e01b0381168252600160e01b900463ffffffff168183015282526001909201910161114e565b505050915250909392505050565b6111b0611471565b6001600160a01b0381166112155760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610559565b61056b81611593565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611271573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112959190611b47565b6001600160a01b0316336001600160a01b0316146112c55760405162461bcd60e51b815260040161055990611b64565b6098541981196098541916146113435760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610559565b609881905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c906020016106a2565b6001600160a01b0381166114085760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610559565b609754604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1609780546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b03163314610ad85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610559565b62034bc08111156115525760405162461bcd60e51b815260206004820152604560248201527f44656c617965645769746864726177616c526f757465722e5f7365745769746860448201527f64726177616c44656c6179426c6f636b733a206e657756616c756520746f6f206064820152646c6172676560d81b608482015260a401610559565b60c95460408051918252602082018390527f4ffb00400574147429ee377a5633386321e66d45d8b14676014b5fa393e61e9e910160405180910390a160c955565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038216600090815260ca602052604081208054600190910154825b848110801561161e57508161161c8285611c45565b105b156116cb576001600160a01b038616600090815260ca602052604081206001016116488386611c45565b8154811061165857611658611c5d565b6000918252602091829020604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff1691810182905260c95490925061169e91611c45565b4310156116ab57506116cb565b80516116c0906001600160e01b031686611c45565b945050600101611607565b6116d58184611c45565b6001600160a01b038716600090815260ca602052604090205583156116fe576116fe868561183a565b7f6b7151500bd0b5cc211bcc47b3029831b769004df4549e8e1c9a69da05bb0943868561172b8487611c45565b604080516001600160a01b039094168452602084019290925290820152606001610e8c565b6097546001600160a01b031615801561177157506001600160a01b03821615155b6117f35760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610559565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a26118368261137a565b5050565b8047101561188a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610559565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146118d7576040519150601f19603f3d011682016040523d82523d6000602084013e6118dc565b606091505b50509050806119535760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610559565b505050565b6001600160a01b038116811461056b57600080fd5b60006020828403121561197f57600080fd5b813561198a81611958565b9392505050565b6000602082840312156119a357600080fd5b5035919050565b80516001600160e01b0316825260209081015163ffffffff16910152565b602080825282518282018190526000919060409081850190868401855b82811015611a08576119f88483516119aa565b92840192908501906001016119e5565b5091979650505050505050565b600060208284031215611a2757600080fd5b813560ff8116811461198a57600080fd5b60008060408385031215611a4b57600080fd5b8235611a5681611958565b946020939093013593505050565b60408101610b5782846119aa565b60008060408385031215611a8557600080fd5b8235611a9081611958565b91506020830135611aa081611958565b809150509250929050565b60008060008060808587031215611ac157600080fd5b8435611acc81611958565b93506020850135611adc81611958565b93969395505050506040820135916060013590565b602080825282518282015282810151604080840181905281516060850181905260009392830191849160808701905b8084101561089b57611b338286516119aa565b938501936001939093019290820190611b20565b600060208284031215611b5957600080fd5b815161198a81611958565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215611bc057600080fd5b8151801515811461198a57600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082821015611c4057611c40611c18565b500390565b60008219821115611c5857611c58611c18565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415611c8757611c87611c18565b5060010190565b634e487b7160e01b600052604160045260246000fd5b60208082526019908201527f5061757361626c653a20696e646578206973207061757365640000000000000060408201526060019056fea264697066735822122028be5fb1babf5ce64b9eafb2fd380ed51a13f09dc7861d1336f53e4f39e35e0f64736f6c634300080c0033","storage":{"0x0":"0xff"}},"0x976ea74026e726554db657fa54763abd0c3a0aa9":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0x9a676e781a523b5d0c0e43731313a708cb607508":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106101f05760003560e01c80637cf72bba1161010f578063d98128c0116100a2578063e921d4fa11610071578063e921d4fa146103c6578063f2fde38b1461044c578063f73b7519146102a9578063fabc1cbc1461045f57600080fd5b8063d98128c014610430578063da16e29b14610322578063df5cf723146102ba578063e58398361461043e57600080fd5b80638da5cb5b116100de5780638da5cb5b146103b5578063a49db732146103c6578063c747075b146103da578063d7b7fa13146103ee57600080fd5b80637cf72bba146103465780638105e04314610354578063855fcc4a1461036b578063886f1195146103a257600080fd5b806339b70e38116101875780636f0c2f74116101565780636f0c2f7414610322578063715018a614610330578063723e59c7146103385780637259a45c1461024257600080fd5b806339b70e38146102ba578063595c6a67146102d55780635ac86ab7146102dd5780635c975abb1461031057600080fd5b80631794bb3c116101c35780631794bb3c1461022f5780631874e5ae14610242578063282670fc1461027257806338c8ee64146102a957600080fd5b80630ffabbce146101f557806310d67a2f14610209578063136439dd1461021c578063175d3205146101f5575b600080fd5b610207610203366004610b25565b5050565b005b610207610217366004610b5a565b610472565b61020761022a366004610b7e565b61052b565b61020761023d366004610b97565b505050565b610258610250366004610b25565b600092915050565b60405163ffffffff90911681526020015b60405180910390f35b610285610280366004610bd8565b61066a565b60408051825163ffffffff9081168252602093840151169281019290925201610269565b6102076102b7366004610b5a565b50565b60005b6040516001600160a01b039091168152602001610269565b610207610685565b6103006102eb366004610c04565b606654600160ff9092169190911b9081161490565b6040519015158152602001610269565b6066545b604051908152602001610269565b610258610250366004610c27565b61020761074c565b610314610250366004610b25565b610207610203366004610c60565b610300610362366004610cd5565b60009392505050565b610385610379366004610c27565b60008060009250925092565b604080519315158452602084019290925290820152606001610269565b6065546102bd906001600160a01b031681565b6033546001600160a01b03166102bd565b6103146103d4366004610b5a565b50600090565b6102076103e8366004610d13565b50505050565b6104016103fc366004610c27565b610760565b60408051825163ffffffff90811682526020808501518216908301529282015190921690820152606001610269565b610300610250366004610c27565b6103006103d4366004610b5a565b61020761045a366004610b5a565b610782565b61020761046d366004610b7e565b6107f8565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e99190610d60565b6001600160a01b0316336001600160a01b0316146105225760405162461bcd60e51b815260040161051990610d7d565b60405180910390fd5b6102b781610954565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610573573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105979190610dc7565b6105b35760405162461bcd60e51b815260040161051990610de9565b6066548181161461062c5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610519565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b60408051808201909152600080825260208201525b92915050565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa1580156106cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f19190610dc7565b61070d5760405162461bcd60e51b815260040161051990610de9565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b610754610a4b565b61075e6000610aa5565b565b604080516060810182526000808252602082018190529181019190915261067f565b61078a610a4b565b6001600160a01b0381166107ef5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610519565b6102b781610aa5565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561084b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086f9190610d60565b6001600160a01b0316336001600160a01b03161461089f5760405162461bcd60e51b815260040161051990610d7d565b60665419811960665419161461091d5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610519565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c9060200161065f565b6001600160a01b0381166109e25760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610519565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b6033546001600160a01b0316331461075e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610519565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03811681146102b757600080fd5b803563ffffffff81168114610b2057600080fd5b919050565b60008060408385031215610b3857600080fd5b8235610b4381610af7565b9150610b5160208401610b0c565b90509250929050565b600060208284031215610b6c57600080fd5b8135610b7781610af7565b9392505050565b600060208284031215610b9057600080fd5b5035919050565b600080600060608486031215610bac57600080fd5b8335610bb781610af7565b92506020840135610bc781610af7565b929592945050506040919091013590565b60008060408385031215610beb57600080fd5b8235610bf681610af7565b946020939093013593505050565b600060208284031215610c1657600080fd5b813560ff81168114610b7757600080fd5b60008060408385031215610c3a57600080fd5b8235610c4581610af7565b91506020830135610c5581610af7565b809150509250929050565b60008060208385031215610c7357600080fd5b823567ffffffffffffffff80821115610c8b57600080fd5b818501915085601f830112610c9f57600080fd5b813581811115610cae57600080fd5b8660208260051b8501011115610cc357600080fd5b60209290920196919550909350505050565b600080600060608486031215610cea57600080fd5b8335610cf581610af7565b9250610d0360208501610b0c565b9150604084013590509250925092565b60008060008060808587031215610d2957600080fd5b8435610d3481610af7565b9350610d4260208601610b0c565b9250610d5060408601610b0c565b9396929550929360600135925050565b600060208284031215610d7257600080fd5b8151610b7781610af7565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b600060208284031215610dd957600080fd5b81518015158114610b7757600080fd5b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b60608201526080019056fea26469706673582212200fdcdd4bbe9965fc5e3814959bc3a46f4e2bf80b0e8c4971318887ad46a8d84564736f6c634300080c0033","storage":{}},"0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0":{"nonce":1,"balance":"0x0","code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063c298557814602d575b600080fd5b600060405190815260200160405180910390f3fea26469706673582212205c7f5f91a0325be43155eb5cb04c77befb735a5810f8939de23702c1530cc5f564736f6c634300080c0033","storage":{}},"0xa0ee7a142d267c1f36714e4a8f75612f20a79720":{"nonce":0,"balance":"0x21e19e0c9bab2400000","code":"0x","storage":{}},"0xa513e6e4b8f2a923d98304ec87f64353c4d5c853":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033","storage":{"0x0":"0x1","0x33":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x65":"0xe7f1725e7734ce288f8367e1bb143e90bb3f0512","0x66":"0x1e","0x97":"0x0","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0xb306bf915c4d645ff596e518faf3f9669b97016","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0xa51c1fc2f0d1a1b8494ed1fe312d7c3a78ed91c0":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106102275760003560e01c806394f649dd11610130578063c6656702116100b8578063df5cf7231161007c578063df5cf72314610596578063e7a050aa146105bd578063f2fde38b146105d0578063f698da25146105e3578063fabc1cbc146105eb57600080fd5b8063c665670214610520578063cbc2bd6214610533578063cd293f6f14610546578063cf756fdf14610570578063df5b35471461058357600080fd5b8063b43b514b116100ff578063b43b514b146104b1578063b5d8b5b8146104c4578063c3c6b3a9146104d7578063c4623ea1146104fa578063c608c7f31461050d57600080fd5b806394f649dd14610433578063967fc0d2146104545780639b4da03d14610467578063b13442711461048a57600080fd5b80635c975abb116101b35780637ecebe00116101825780637ecebe00146103b3578063886f1195146103d35780638b8aac3c146103e65780638c80d4e51461040f5780638da5cb5b1461042257600080fd5b80635c975abb14610355578063663c1de41461035d578063715018a6146103805780637a7e0d921461038857600080fd5b80634665bcda116101fa5780634665bcda146102a157806348825e94146102e05780634e5a426314610307578063595c6a671461031a5780635ac86ab71461032257600080fd5b806310d67a2f1461022c578063136439dd1461024157806320606b701461025457806332e89ace1461028e575b600080fd5b61023f61023a366004612b4a565b6105fe565b005b61023f61024f366004612b67565b6106ba565b61027b7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6040519081526020015b60405180910390f35b61027b61029c366004612c00565b6107f9565b6102c87f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85381565b6040516001600160a01b039091168152602001610285565b61027b7f4337f82d142e41f2a8c10547cd8c859bddb92262a61058e77842e24d9dea922481565b61023f610315366004612ced565b610ae7565b61023f610b1f565b610345610330366004612d26565b609854600160ff9092169190911b9081161490565b6040519015158152602001610285565b60985461027b565b61034561036b366004612b4a565b60d16020526000908152604090205460ff1681565b61023f610be6565b61027b610396366004612d49565b60cd60209081526000928352604080842090915290825290205481565b61027b6103c1366004612b4a565b60ca6020526000908152604090205481565b6097546102c8906001600160a01b031681565b61027b6103f4366004612b4a565b6001600160a01b0316600090815260ce602052604090205490565b61023f61041d366004612d77565b610bfa565b6033546001600160a01b03166102c8565b610446610441366004612b4a565b610c53565b604051610285929190612e2c565b60cb546102c8906001600160a01b031681565b610345610475366004612b4a565b60d36020526000908152604090205460ff1681565b6102c87f0000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f81565b61027b6104bf366004612fd5565b610dd3565b61023f6104d23660046130f0565b610e20565b6103456104e5366004612b67565b60cf6020526000908152604090205460ff1681565b61023f610508366004613132565b610f94565b61023f61051b366004613183565b610fe8565b61023f61052e366004612b4a565b6110a0565b6102c86105413660046131d6565b6110b1565b610559610554366004612fd5565b6110e9565b604080519215158352602083019190915201610285565b61023f61057e366004613132565b61117d565b61023f610591366004613202565b6112b1565b6102c87f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc981565b61027b6105cb366004612d77565b6114da565b61023f6105de366004612b4a565b6115a3565b61027b611619565b61023f6105f9366004612b67565b611657565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610651573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610675919061326e565b6001600160a01b0316336001600160a01b0316146106ae5760405162461bcd60e51b81526004016106a59061328b565b60405180910390fd5b6106b7816117b3565b50565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610702573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061072691906132d5565b6107425760405162461bcd60e51b81526004016106a5906132f2565b609854818116146107bb5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c697479000000000000000060648201526084016106a5565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b6098546000908190600190811614156108505760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b60448201526064016106a5565b600260655414156108a35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106a5565b60026065556001600160a01b038816600090815260d3602052604090205460ff161561094a5760405162461bcd60e51b815260206004820152604a60248201527f53747261746567794d616e616765722e6465706f736974496e746f537472617460448201527f656779576974685369676e61747572653a207468697264207472616e736665726064820152691cc8191a5cd8589b195960b21b608482015260a4016106a5565b428410156109cc5760405162461bcd60e51b815260206004820152604360248201527f53747261746567794d616e616765722e6465706f736974496e746f537472617460448201527f656779576974685369676e61747572653a207369676e617475726520657870696064820152621c995960ea1b608482015260a4016106a5565b6001600160a01b03858116600081815260ca602090815260408083205481517f4337f82d142e41f2a8c10547cd8c859bddb92262a61058e77842e24d9dea922493810193909352908201939093528b84166060820152928a16608084015260a0830189905260c0830182905260e0830187905290916101000160408051601f1981840301815291815281516020928301206001600160a01b038a16600090815260ca9093529082206001850190559150610a84611619565b60405161190160f01b6020820152602281019190915260428101839052606201604051602081830303815290604052805190602001209050610ac78882886118aa565b610ad3888c8c8c611a69565b60016065559b9a5050505050505050505050565b60cb546001600160a01b03163314610b115760405162461bcd60e51b81526004016106a59061333a565b610b1b8282611c38565b5050565b60975460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015610b67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8b91906132d5565b610ba75760405162461bcd60e51b81526004016106a5906132f2565b600019609881905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b610bee611ca6565b610bf86000611d00565b565b336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc91614610c425760405162461bcd60e51b81526004016106a5906133a4565b610c4d838383611d52565b50505050565b6001600160a01b038116600090815260ce60205260408120546060918291908167ffffffffffffffff811115610c8b57610c8b612b90565b604051908082528060200260200182016040528015610cb4578160200160208202803683370190505b50905060005b82811015610d45576001600160a01b038616600090815260cd6020908152604080832060ce9092528220805491929184908110610cf957610cf9613402565b60009182526020808320909101546001600160a01b031683528201929092526040019020548251839083908110610d3257610d32613402565b6020908102919091010152600101610cba565b5060ce6000866001600160a01b03166001600160a01b031681526020019081526020016000208181805480602002602001604051908101604052809291908181526020018280548015610dc157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610da3575b50505050509150935093505050915091565b80516020808301516040808501516060860151608087015160a08801519351600097610e03979096959101613418565b604051602081830303815290604052805190602001209050919050565b60cb546001600160a01b03163314610e4a5760405162461bcd60e51b81526004016106a59061333a565b8060005b81811015610c4d5760d16000858584818110610e6c57610e6c613402565b9050602002016020810190610e819190612b4a565b6001600160a01b0316815260208101919091526040016000205460ff1615610f8c57600060d16000868685818110610ebb57610ebb613402565b9050602002016020810190610ed09190612b4a565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f4074413b4b443e4e58019f2855a8765113358c7c72e39509c6af45fc0f5ba030848483818110610f2b57610f2b613402565b9050602002016020810190610f409190612b4a565b6040516001600160a01b03909116815260200160405180910390a1610f8c848483818110610f7057610f70613402565b9050602002016020810190610f859190612b4a565b6000611c38565b600101610e4e565b336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc91614610fdc5760405162461bcd60e51b81526004016106a5906133a4565b610c4d84848484611eae565b336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc916146110305760405162461bcd60e51b81526004016106a5906133a4565b604051636ce5768960e11b81526001600160a01b03858116600483015282811660248301526044820184905284169063d9caed1290606401600060405180830381600087803b15801561108257600080fd5b505af1158015611096573d6000803e3d6000fd5b5050505050505050565b6110a8611ca6565b6106b78161213b565b60ce60205281600052604060002081815481106110cd57600080fd5b6000918252602090912001546001600160a01b03169150829050565b600080336001600160a01b037f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc916146111345760405162461bcd60e51b81526004016106a5906133a4565b600061113f84610dd3565b600081815260cf60205260408120549192509060ff16156111745750600081815260cf60205260409020805460ff1916905560015b92509050915091565b600054610100900460ff161580801561119d5750600054600160ff909116105b806111b75750303b1580156111b7575060005460ff166001145b61121a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106a5565b6000805460ff19166001179055801561123d576000805461ff0019166101001790555b6112456121a4565b60c955611252838361223b565b61125b85611d00565b6112648461213b565b80156112aa576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60cb546001600160a01b031633146112db5760405162461bcd60e51b81526004016106a59061333a565b8281146113645760405162461bcd60e51b815260206004820152604b60248201527f53747261746567794d616e616765722e61646453747261746567696573546f4460448201527f65706f73697457686974656c6973743a206172726179206c656e67746873206460648201526a0de40dcdee840dac2e8c6d60ab1b608482015260a4016106a5565b8260005b818110156114d25760d1600087878481811061138657611386613402565b905060200201602081019061139b9190612b4a565b6001600160a01b0316815260208101919091526040016000205460ff166114ca57600160d160008888858181106113d4576113d4613402565b90506020020160208101906113e99190612b4a565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f0c35b17d91c96eb2751cd456e1252f42a386e524ef9ff26ecc9950859fdc04fe86868381811061144457611444613402565b90506020020160208101906114599190612b4a565b6040516001600160a01b03909116815260200160405180910390a16114ca86868381811061148957611489613402565b905060200201602081019061149e9190612b4a565b8585848181106114b0576114b0613402565b90506020020160208101906114c59190613491565b611c38565b600101611368565b505050505050565b6098546000908190600190811614156115315760405162461bcd60e51b815260206004820152601960248201527814185d5cd8589b194e881a5b99195e081a5cc81c185d5cd959603a1b60448201526064016106a5565b600260655414156115845760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106a5565b600260655561159533868686611a69565b600160655595945050505050565b6115ab611ca6565b6001600160a01b0381166116105760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016106a5565b6106b781611d00565b60007f0000000000000000000000000000000000000000000000000000000000007a6946141561164a575060c95490565b6116526121a4565b905090565b609760009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ce919061326e565b6001600160a01b0316336001600160a01b0316146116fe5760405162461bcd60e51b81526004016106a59061328b565b60985419811960985419161461177c5760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c697479000000000000000060648201526084016106a5565b609881905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c906020016107ee565b6001600160a01b0381166118415760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a4016106a5565b609754604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1609780546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0383163b156119c957604051630b135d3f60e11b808252906001600160a01b03851690631626ba7e906118ea9086908690600401613506565b602060405180830381865afa158015611907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192b919061351f565b6001600160e01b031916146119c45760405162461bcd60e51b815260206004820152605360248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a2045524331323731207369676e6174757265206064820152721d995c9a599a58d85d1a5bdb8819985a5b1959606a1b608482015260a4016106a5565b505050565b826001600160a01b03166119dd8383612321565b6001600160a01b0316146119c45760405162461bcd60e51b815260206004820152604760248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a207369676e6174757265206e6f742066726f6d6064820152661039b4b3b732b960c91b608482015260a4016106a5565b6001600160a01b038316600090815260d16020526040812054849060ff16611b0f5760405162461bcd60e51b815260206004820152604d60248201527f53747261746567794d616e616765722e6f6e6c7953747261746567696573576860448201527f6974656c6973746564466f724465706f7369743a207374726174656779206e6f60648201526c1d081dda1a5d195b1a5cdd1959609a1b608482015260a4016106a5565b611b246001600160a01b038516338786612345565b6040516311f9fbc960e21b81526001600160a01b038581166004830152602482018590528616906347e7ef24906044016020604051808303816000875af1158015611b73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b979190613549565b9150611ba586858785611eae565b604051631452b9d760e11b81526001600160a01b0387811660048301528681166024830152604482018490527f000000000000000000000000cf7ed3acca5a467e9e704c703e8d87f634fb0fc916906328a573ae90606401600060405180830381600087803b158015611c1757600080fd5b505af1158015611c2b573d6000803e3d6000fd5b5050505050949350505050565b604080516001600160a01b038416815282151560208201527f77d930df4937793473a95024d87a98fd2ccb9e92d3c2463b3dacd65d3e6a5786910160405180910390a16001600160a01b0391909116600090815260d360205260409020805460ff1916911515919091179055565b6033546001600160a01b03163314610bf85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106a5565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600081611dc75760405162461bcd60e51b815260206004820152603e60248201527f53747261746567794d616e616765722e5f72656d6f76655368617265733a207360448201527f68617265416d6f756e742073686f756c64206e6f74206265207a65726f21000060648201526084016106a5565b6001600160a01b03808516600090815260cd602090815260408083209387168352929052205480831115611e595760405162461bcd60e51b815260206004820152603360248201527f53747261746567794d616e616765722e5f72656d6f76655368617265733a20736044820152720d0c2e4ca82dadeeadce840e8dede40d0d2ced606b1b60648201526084016106a5565b6001600160a01b03808616600090815260cd602090815260408083209388168352929052208382039081905590831415611ea157611e97858561239f565b6001915050611ea7565b60009150505b9392505050565b6001600160a01b038416611f2a5760405162461bcd60e51b815260206004820152603960248201527f53747261746567794d616e616765722e5f6164645368617265733a207374616b60448201527f65722063616e6e6f74206265207a65726f20616464726573730000000000000060648201526084016106a5565b80611f965760405162461bcd60e51b815260206004820152603660248201527f53747261746567794d616e616765722e5f6164645368617265733a207368617260448201527565732073686f756c64206e6f74206265207a65726f2160501b60648201526084016106a5565b6001600160a01b03808516600090815260cd60209081526040808320938616835292905220546120a7576001600160a01b038416600090815260ce6020908152604090912054106120685760405162461bcd60e51b815260206004820152605060248201527f53747261746567794d616e616765722e5f6164645368617265733a206465706f60448201527f73697420776f756c6420657863656564204d41585f5354414b45525f5354524160648201526f0a88a8eb2be9892a6a8be988a9c8ea8960831b608482015260a4016106a5565b6001600160a01b03848116600090815260ce602090815260408220805460018101825590835291200180546001600160a01b0319169184169190911790555b6001600160a01b03808516600090815260cd60209081526040808320938616835292905290812080548392906120de908490613578565b9091555050604080516001600160a01b03868116825285811660208301528416818301526060810183905290517f7cfff908a4b583f36430b25d75964c458d8ede8a99bd61be750e97ee1b2f3a969181900360800190a150505050565b60cb54604080516001600160a01b03928316815291831660208301527f4264275e593955ff9d6146a51a4525f6ddace2e81db9391abcc9d1ca48047d29910160405180910390a160cb80546001600160a01b0319166001600160a01b0392909216919091179055565b604080518082018252600a81526922b4b3b2b72630bcb2b960b11b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f71b625cfad44bac63b13dba07f2e1d6084ee04b6f8752101ece6126d584ee6ea81840152466060820152306080808301919091528351808303909101815260a0909101909252815191012090565b6097546001600160a01b031615801561225c57506001600160a01b03821615155b6122de5760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a4016106a5565b609881905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2610b1b826117b3565b60008060006123308585612591565b9150915061233d81612601565b509392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610c4d9085906127bc565b6001600160a01b038216600090815260ce6020526040812054905b818110156124ba576001600160a01b03848116600090815260ce60205260409020805491851691839081106123f1576123f1613402565b6000918252602090912001546001600160a01b031614156124b2576001600160a01b038416600090815260ce60205260409020805461243290600190613590565b8154811061244257612442613402565b60009182526020808320909101546001600160a01b03878116845260ce909252604090922080549190921691908390811061247f5761247f613402565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506124ba565b6001016123ba565b818114156125425760405162461bcd60e51b815260206004820152604960248201527f53747261746567794d616e616765722e5f72656d6f766553747261746567794660448201527f726f6d5374616b657253747261746567794c6973743a207374726174656779206064820152681b9bdd08199bdd5b9960ba1b608482015260a4016106a5565b6001600160a01b038416600090815260ce60205260409020805480612569576125696135a7565b600082815260209020810160001990810180546001600160a01b031916905501905550505050565b6000808251604114156125c85760208301516040840151606085015160001a6125bc8782858561288e565b945094505050506125fa565b8251604014156125f257602083015160408401516125e786838361297b565b9350935050506125fa565b506000905060025b9250929050565b6000816004811115612615576126156135bd565b141561261e5750565b6001816004811115612632576126326135bd565b14156126805760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016106a5565b6002816004811115612694576126946135bd565b14156126e25760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016106a5565b60038160048111156126f6576126f66135bd565b141561274f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016106a5565b6004816004811115612763576127636135bd565b14156106b75760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016106a5565b6000612811826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166129b49092919063ffffffff16565b8051909150156119c4578080602001905181019061282f91906132d5565b6119c45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016106a5565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156128c55750600090506003612972565b8460ff16601b141580156128dd57508460ff16601c14155b156128ee5750600090506004612972565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612942573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661296b57600060019250925050612972565b9150600090505b94509492505050565b6000806001600160ff1b0383168161299860ff86901c601b613578565b90506129a68782888561288e565b935093505050935093915050565b60606129c384846000856129cb565b949350505050565b606082471015612a2c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016106a5565b6001600160a01b0385163b612a835760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106a5565b600080866001600160a01b03168587604051612a9f91906135d3565b60006040518083038185875af1925050503d8060008114612adc576040519150601f19603f3d011682016040523d82523d6000602084013e612ae1565b606091505b5091509150612af1828286612afc565b979650505050505050565b60608315612b0b575081611ea7565b825115612b1b5782518084602001fd5b8160405162461bcd60e51b81526004016106a591906135ef565b6001600160a01b03811681146106b757600080fd5b600060208284031215612b5c57600080fd5b8135611ea781612b35565b600060208284031215612b7957600080fd5b5035919050565b8035612b8b81612b35565b919050565b634e487b7160e01b600052604160045260246000fd5b60405160c0810167ffffffffffffffff81118282101715612bc957612bc9612b90565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612bf857612bf8612b90565b604052919050565b60008060008060008060c08789031215612c1957600080fd5b8635612c2481612b35565b9550602087810135612c3581612b35565b9550604088013594506060880135612c4c81612b35565b93506080880135925060a088013567ffffffffffffffff80821115612c7057600080fd5b818a0191508a601f830112612c8457600080fd5b813581811115612c9657612c96612b90565b612ca8601f8201601f19168501612bcf565b91508082528b84828501011115612cbe57600080fd5b80848401858401376000848284010152508093505050509295509295509295565b80151581146106b757600080fd5b60008060408385031215612d0057600080fd5b8235612d0b81612b35565b91506020830135612d1b81612cdf565b809150509250929050565b600060208284031215612d3857600080fd5b813560ff81168114611ea757600080fd5b60008060408385031215612d5c57600080fd5b8235612d6781612b35565b91506020830135612d1b81612b35565b600080600060608486031215612d8c57600080fd5b8335612d9781612b35565b92506020840135612da781612b35565b929592945050506040919091013590565b600081518084526020808501945080840160005b83811015612df15781516001600160a01b031687529582019590820190600101612dcc565b509495945050505050565b600081518084526020808501945080840160005b83811015612df157815187529582019590820190600101612e10565b604081526000612e3f6040830185612db8565b8281036020840152612e518185612dfc565b95945050505050565b600067ffffffffffffffff821115612e7457612e74612b90565b5060051b60200190565b600082601f830112612e8f57600080fd5b81356020612ea4612e9f83612e5a565b612bcf565b82815260059290921b84018101918181019086841115612ec357600080fd5b8286015b84811015612ee7578035612eda81612b35565b8352918301918301612ec7565b509695505050505050565b600082601f830112612f0357600080fd5b81356020612f13612e9f83612e5a565b82815260059290921b84018101918181019086841115612f3257600080fd5b8286015b84811015612ee75780358352918301918301612f36565b600060408284031215612f5f57600080fd5b6040516040810181811067ffffffffffffffff82111715612f8257612f82612b90565b6040529050808235612f9381612b35565b815260208301356bffffffffffffffffffffffff81168114612fb457600080fd5b6020919091015292915050565b803563ffffffff81168114612b8b57600080fd5b600060208284031215612fe757600080fd5b813567ffffffffffffffff80821115612fff57600080fd5b9083019060e0828603121561301357600080fd5b61301b612ba6565b82358281111561302a57600080fd5b61303687828601612e7e565b82525060208301358281111561304b57600080fd5b61305787828601612ef2565b60208301525061306960408401612b80565b604082015261307b8660608501612f4d565b606082015261308c60a08401612fc1565b608082015261309d60c08401612b80565b60a082015295945050505050565b60008083601f8401126130bd57600080fd5b50813567ffffffffffffffff8111156130d557600080fd5b6020830191508360208260051b85010111156125fa57600080fd5b6000806020838503121561310357600080fd5b823567ffffffffffffffff81111561311a57600080fd5b613126858286016130ab565b90969095509350505050565b6000806000806080858703121561314857600080fd5b843561315381612b35565b9350602085013561316381612b35565b9250604085013561317381612b35565b9396929550929360600135925050565b6000806000806080858703121561319957600080fd5b84356131a481612b35565b935060208501356131b481612b35565b92506040850135915060608501356131cb81612b35565b939692955090935050565b600080604083850312156131e957600080fd5b82356131f481612b35565b946020939093013593505050565b6000806000806040858703121561321857600080fd5b843567ffffffffffffffff8082111561323057600080fd5b61323c888389016130ab565b9096509450602087013591508082111561325557600080fd5b50613262878288016130ab565b95989497509550505050565b60006020828403121561328057600080fd5b8151611ea781612b35565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b6000602082840312156132e757600080fd5b8151611ea781612cdf565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b60208082526044908201527f53747261746567794d616e616765722e6f6e6c7953747261746567795768697460408201527f656c69737465723a206e6f742074686520737472617465677957686974656c6960608201526339ba32b960e11b608082015260a00190565b602080825260409082018190527f53747261746567794d616e616765722e6f6e6c7944656c65676174696f6e4d61908201527f6e616765723a206e6f74207468652044656c65676174696f6e4d616e61676572606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60e08152600061342b60e0830189612db8565b828103602084015261343d8189612dfc565b6001600160a01b0397881660408501528651881660608501526020909601516bffffffffffffffffffffffff166080840152505063ffffffff9290921660a083015290921660c09092019190915292915050565b6000602082840312156134a357600080fd5b8135611ea781612cdf565b60005b838110156134c95781810151838201526020016134b1565b83811115610c4d5750506000910152565b600081518084526134f28160208601602086016134ae565b601f01601f19169290920160200192915050565b8281526040602082015260006129c360408301846134da565b60006020828403121561353157600080fd5b81516001600160e01b031981168114611ea757600080fd5b60006020828403121561355b57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561358b5761358b613562565b500190565b6000828210156135a2576135a2613562565b500390565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b600082516135e58184602087016134ae565b9190910192915050565b602081526000611ea760208301846134da56fea2646970667358221220af8db90c83e081e833ccb506edfe58292320542a275bdf8901b5381d81c5ab5f64736f6c634300080c0033","storage":{"0x0":"0xff"}},"0xb7f8bc63bbcad18155201308c8f3540b07f84f5e":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b50600436106103785760003560e01c806360d7faed116101d3578063b7f06ebe11610104578063cf80873e116100a2578063f16172b01161007c578063f16172b01461097d578063f2fde38b14610990578063f698da25146109a3578063fabc1cbc146109ab57600080fd5b8063cf80873e14610936578063da8be86414610957578063eea9064b1461096a57600080fd5b8063c488375a116100de578063c488375a14610853578063c5e480db14610873578063c94b511114610919578063ca661c041461092c57600080fd5b8063b7f06ebe146107f9578063bb45fef21461081c578063c448feb81461084a57600080fd5b8063886f1195116101715780639104c3191161014b5780639104c3191461078457806399be81c81461079f578063a1788484146107b2578063b1344271146107d257600080fd5b8063886f1195146107405780638da5cb5b14610753578063900413471461076457600080fd5b80636d70f7ae116101ad5780636d70f7ae146106e7578063715018a6146106fa578063778e55f3146107025780637f5480711461072d57600080fd5b806360d7faed14610698578063635bbd10146106ab57806365da1264146106be57600080fd5b806329c77d4f116102ad5780634fc40b611161024b5780635ac86ab7116102255780635ac86ab71461062e5780635c975abb146106515780635cfe8d2c146106595780635f966f141461066c57600080fd5b80634fc40b6114610609578063595c6a6714610613578063597b36da1461061b57600080fd5b80633cdeb5e0116102875780633cdeb5e0146105695780633e28391d1461059857806343377382146105bb5780634665bcda146105e257600080fd5b806329c77d4f146104f7578063334043961461051757806339b70e381461052a57600080fd5b8063136439dd1161031a5780631bbce091116102f45780631bbce0911461049757806320606b70146104aa57806322bf40e4146104d157806328a573ae146104e457600080fd5b8063136439dd146104385780631522bf021461044b578063169283651461045e57600080fd5b80630dd8dd02116103565780630dd8dd02146103dd5780630f589e59146103fd57806310d67a2f14610412578063132d49671461042557600080fd5b80630449ca391461037d57806304a4f979146103a35780630b9f487a146103ca575b600080fd5b61039061038b366004614adb565b6109be565b6040519081526020015b60405180910390f35b6103907f14bde674c9f64b2ad00eaaee4a8bed1fabef35c7507e3c5b9cfc9436909a2dad81565b6103906103d8366004614b41565b610a43565b6103f06103eb366004614adb565b610b05565b60405161039a9190614b9c565b61041061040b366004614c39565b610e6e565b005b610410610420366004614c8c565b610fbe565b610410610433366004614cb0565b611071565b610410610446366004614cf1565b611128565b610410610459366004614d0a565b611267565b61039061046c366004614c8c565b6001600160a01b0316600090815260996020526040902060010154600160a01b900463ffffffff1690565b6103906104a5366004614cb0565b61127b565b6103907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6104106104df366004614d75565b6112a9565b6104106104f2366004614cb0565b6113ed565b610390610505366004614c8c565b609b6020526000908152604090205481565b610410610525366004614e1c565b61149d565b6105517f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c981565b6040516001600160a01b03909116815260200161039a565b610551610577366004614c8c565b6001600160a01b039081166000908152609960205260409020600101541690565b6105ab6105a6366004614c8c565b6115da565b604051901515815260200161039a565b6103907f39111bc4a4d688e1f685123d7497d4615370152a8ee4a0593e647bd06ad8bb0b81565b6105517f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85381565b6103906213c68081565b6104106115fa565b61039061062936600461513b565b6116c1565b6105ab61063c366004615177565b606654600160ff9092169190911b9081161490565b606654610390565b6104106106673660046151ed565b6116f1565b61055161067a366004614c8c565b6001600160a01b039081166000908152609960205260409020541690565b6104106106a636600461534d565b61199c565b6104106106b9366004614cf1565b611a37565b6105516106cc366004614c8c565b609a602052600090815260409020546001600160a01b031681565b6105ab6106f5366004614c8c565b611a48565b610410611a68565b6103906107103660046153dc565b609860209081526000928352604080842090915290825290205481565b61041061073b3660046154bd565b611a7c565b606554610551906001600160a01b031681565b6033546001600160a01b0316610551565b61077761077236600461554d565b611b81565b60405161039a91906155d7565b61055173beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac081565b6104106107ad3660046155ea565b611c5b565b6103906107c0366004614c8c565b609f6020526000908152604090205481565b6105517f0000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f81565b6105ab610807366004614cf1565b609e6020526000908152604090205460ff1681565b6105ab61082a36600461561f565b609c60209081526000928352604080842090915290825290205460ff1681565b610390609d5481565b610390610861366004614c8c565b60a16020526000908152604090205481565b6108e3610881366004614c8c565b6040805160608082018352600080835260208084018290529284018190526001600160a01b03948516815260998352839020835191820184528054851682526001015493841691810191909152600160a01b90920463ffffffff169082015290565b6040805182516001600160a01b039081168252602080850151909116908201529181015163ffffffff169082015260600161039a565b61039061092736600461564b565b611d2d565b61039062034bc081565b610949610944366004614c8c565b611de6565b60405161039a9291906156cc565b6103f0610965366004614c8c565b61219e565b6104106109783660046156f1565b612662565b61041061098b366004615749565b61266e565b61041061099e366004614c8c565b6126ff565b610390612775565b6104106109b9366004614cf1565b6127b3565b609d54600090815b83811015610a3b57600060a160008787858181106109e6576109e6615765565b90506020020160208101906109fb9190614c8c565b6001600160a01b03166001600160a01b0316815260200190815260200160002054905082811115610a2a578092505b50610a3481615791565b90506109c6565b509392505050565b604080517f14bde674c9f64b2ad00eaaee4a8bed1fabef35c7507e3c5b9cfc9436909a2dad6020808301919091526001600160a01b038681168385015288811660608401528716608083015260a0820185905260c08083018590528351808403909101815260e0909201909252805191012060009081610ac1612775565b60405161190160f01b602082015260228101919091526042810183905260620160408051808303601f19018152919052805160209091012098975050505050505050565b60665460609060019060029081161415610b3a5760405162461bcd60e51b8152600401610b31906157ac565b60405180910390fd5b6000836001600160401b03811115610b5457610b54614ebe565b604051908082528060200260200182016040528015610b7d578160200160208202803683370190505b50336000908152609a60205260408120549192506001600160a01b03909116905b85811015610e6357868682818110610bb857610bb8615765565b9050602002810190610bca91906157e3565b610bd8906020810190615803565b9050878783818110610bec57610bec615765565b9050602002810190610bfe91906157e3565b610c089080615803565b905014610c7d5760405162461bcd60e51b815260206004820152603860248201527f44656c65676174696f6e4d616e616765722e717565756557697468647261776160448201527f6c3a20696e707574206c656e677468206d69736d6174636800000000000000006064820152608401610b31565b33878783818110610c9057610c90615765565b9050602002810190610ca291906157e3565b610cb3906060810190604001614c8c565b6001600160a01b031614610d2f5760405162461bcd60e51b815260206004820152603c60248201527f44656c65676174696f6e4d616e616765722e717565756557697468647261776160448201527f6c3a2077697468647261776572206d757374206265207374616b6572000000006064820152608401610b31565b610e343383898985818110610d4657610d46615765565b9050602002810190610d5891906157e3565b610d69906060810190604001614c8c565b8a8a86818110610d7b57610d7b615765565b9050602002810190610d8d91906157e3565b610d979080615803565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508e92508d9150889050818110610ddd57610ddd615765565b9050602002810190610def91906157e3565b610dfd906020810190615803565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061290f92505050565b838281518110610e4657610e46615765565b602090810291909101015280610e5b81615791565b915050610b9e565b509095945050505050565b336000908152609960205260409020546001600160a01b031615610f085760405162461bcd60e51b815260206004820152604560248201527f44656c65676174696f6e4d616e616765722e726567697374657241734f70657260448201527f61746f723a206f70657261746f722068617320616c72656164792072656769736064820152641d195c995960da1b608482015260a401610b31565b610f123384612ecf565b604080518082019091526060815260006020820152610f34338083600061316b565b336001600160a01b03167f8e8485583a2310d41f7c82b9427d0bd49bad74bb9cff9d3402a29d8f9b28a0e285604051610f6d919061584c565b60405180910390a2336001600160a01b03167f02a919ed0e2acad1dd90f17ef2fa4ae5462ee1339170034a8531cca4b67080908484604051610fb092919061589e565b60405180910390a250505050565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611011573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103591906158cd565b6001600160a01b0316336001600160a01b0316146110655760405162461bcd60e51b8152600401610b31906158ea565b61106e81613510565b50565b336001600160a01b037f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c91614806110d05750336001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85316145b6110ec5760405162461bcd60e51b8152600401610b3190615934565b6110f5836115da565b15611123576001600160a01b038084166000908152609a60205260409020541661112181858585613607565b505b505050565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015611170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111949190615991565b6111b05760405162461bcd60e51b8152600401610b31906159ae565b606654818116146112295760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e70617573653a20696e76616c696420617474656d70742060448201527f746f20756e70617573652066756e6374696f6e616c69747900000000000000006064820152608401610b31565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d906020015b60405180910390a250565b61126f613682565b611121848484846136dc565b6001600160a01b0383166000908152609b60205260408120546112a085828686611d2d565b95945050505050565b600054610100900460ff16158080156112c95750600054600160ff909116105b806112e35750303b1580156112e3575060005460ff166001145b6113465760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610b31565b6000805460ff191660011790558015611369576000805461ff0019166101001790555b6113738888613902565b61137b6139e8565b60975561138789613a7f565b61139086613ad1565b61139c858585856136dc565b80156113e2576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050505050565b336001600160a01b037f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c916148061144c5750336001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85316145b6114685760405162461bcd60e51b8152600401610b3190615934565b611471836115da565b15611123576001600160a01b038084166000908152609a60205260409020541661112181858585613bcb565b606654600290600490811614156114c65760405162461bcd60e51b8152600401610b31906157ac565b600260c95414156115195760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b31565b600260c95560005b888110156115c9576115b98a8a8381811061153e5761153e615765565b905060200281019061155091906159f6565b89898481811061156257611562615765565b90506020028101906115749190615803565b89898681811061158657611586615765565b9050602002013588888781811061159f5761159f615765565b90506020020160208101906115b49190615a0c565b613c46565b6115c281615791565b9050611521565b5050600160c9555050505050505050565b6001600160a01b039081166000908152609a602052604090205416151590565b60655460405163237dfb4760e11b81523360048201526001600160a01b03909116906346fbf68e90602401602060405180830381865afa158015611642573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116669190615991565b6116825760405162461bcd60e51b8152600401610b31906159ae565b600019606681905560405190815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a2565b6000816040516020016116d49190615a9d565b604051602081830303815290604052805190602001209050919050565b60005b815181101561199857600082828151811061171157611711615765565b602002602001015190506000807f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c96001600160a01b031663cd293f6f846040518263ffffffff1660e01b815260040161176a9190615ab0565b60408051808303816000875af1158015611788573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ac9190615b5c565b91509150811561198a576040808401516001600160a01b0381166000908152609f602052918220805491928291906117e383615791565b919050555060006040518060e00160405280846001600160a01b031681526020018760a001516001600160a01b031681526020018760600151600001516001600160a01b03168152602001838152602001876080015163ffffffff16815260200187600001518152602001876020015181525090506000611863826116c1565b6000818152609e602052604090205490915060ff16156118f95760405162461bcd60e51b815260206004820152604560248201527f44656c65676174696f6e4d616e616765722e6d6967726174655175657565645760448201527f69746864726177616c733a207769746864726177616c20616c72656164792065606482015264786973747360d81b608482015260a401610b31565b6000818152609e602052604090819020805460ff19166001179055517f9009ab153e8014fbfb02f2217f5cde7aa7f9ad734ae85ca3ee3f4ca2fdd499f9906119449083908590615b8a565b60405180910390a160408051868152602081018390527fdc00758b65eef71dc3780c04ebe36cab6bdb266c3a698187e29e0f0dca012630910160405180910390a1505050505b8360010193505050506116f4565b5050565b606654600290600490811614156119c55760405162461bcd60e51b8152600401610b31906157ac565b600260c9541415611a185760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b31565b600260c955611a2a8686868686613c46565b5050600160c95550505050565b611a3f613682565b61106e81613ad1565b6001600160a01b0390811660009081526099602052604090205416151590565b611a70613682565b611a7a6000613a7f565b565b4283602001511015611b005760405162461bcd60e51b815260206004820152604160248201527f44656c65676174696f6e4d616e616765722e64656c6567617465546f4279536960448201527f676e61747572653a207374616b6572207369676e6174757265206578706972656064820152601960fa1b608482015260a401610b31565b6000609b6000876001600160a01b03166001600160a01b031681526020019081526020016000205490506000611b3c8783888860200151611d2d565b6001600160a01b0388166000908152609b602052604090206001840190558551909150611b6c9088908390614430565b611b788787868661316b565b50505050505050565b6060600082516001600160401b03811115611b9e57611b9e614ebe565b604051908082528060200260200182016040528015611bc7578160200160208202803683370190505b50905060005b8351811015610a3b576001600160a01b03851660009081526098602052604081208551909190869084908110611c0557611c05615765565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054828281518110611c4057611c40615765565b6020908102919091010152611c5481615791565b9050611bcd565b611c6433611a48565b611ce65760405162461bcd60e51b815260206004820152604760248201527f44656c65676174696f6e4d616e616765722e7570646174654f70657261746f7260448201527f4d657461646174615552493a2063616c6c6572206d75737420626520616e206f6064820152663832b930ba37b960c91b608482015260a401610b31565b336001600160a01b03167f02a919ed0e2acad1dd90f17ef2fa4ae5462ee1339170034a8531cca4b67080908383604051611d2192919061589e565b60405180910390a25050565b604080517f39111bc4a4d688e1f685123d7497d4615370152a8ee4a0593e647bd06ad8bb0b6020808301919091526001600160a01b0387811683850152851660608301526080820186905260a08083018590528351808403909101815260c0909201909252805191012060009081611da3612775565b60405161190160f01b602082015260228101919091526042810183905260620160408051808303601f190181529190528051602090910120979650505050505050565b6040516360f4062b60e01b81526001600160a01b03828116600483015260609182916000917f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c853909116906360f4062b90602401602060405180830381865afa158015611e56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7a9190615ba3565b6040516394f649dd60e01b81526001600160a01b03868116600483015291925060009182917f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c9909116906394f649dd90602401600060405180830381865afa158015611eea573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f129190810190615c17565b9150915060008313611f2957909590945092505050565b606080835160001415611fe3576040805160018082528183019092529060208083019080368337505060408051600180825281830190925292945090506020808301908036833701905050905073beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac082600081518110611f9e57611f9e615765565b60200260200101906001600160a01b031690816001600160a01b0316815250508481600081518110611fd257611fd2615765565b602002602001018181525050612191565b8351611ff0906001615cd1565b6001600160401b0381111561200757612007614ebe565b604051908082528060200260200182016040528015612030578160200160208202803683370190505b50915081516001600160401b0381111561204c5761204c614ebe565b604051908082528060200260200182016040528015612075578160200160208202803683370190505b50905060005b845181101561210f5784818151811061209657612096615765565b60200260200101518382815181106120b0576120b0615765565b60200260200101906001600160a01b031690816001600160a01b0316815250508381815181106120e2576120e2615765565b60200260200101518282815181106120fc576120fc615765565b602090810291909101015260010161207b565b5073beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac082600184516121349190615ce9565b8151811061214457612144615765565b60200260200101906001600160a01b031690816001600160a01b0316815250508481600184516121749190615ce9565b8151811061218457612184615765565b6020026020010181815250505b9097909650945050505050565b606654606090600190600290811614156121ca5760405162461bcd60e51b8152600401610b31906157ac565b6121d3836115da565b6122535760405162461bcd60e51b8152602060048201526044602482018190527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a207374908201527f616b6572206d7573742062652064656c65676174656420746f20756e64656c656064820152636761746560e01b608482015260a401610b31565b61225c83611a48565b156122cf5760405162461bcd60e51b815260206004820152603d60248201527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a206f7060448201527f657261746f72732063616e6e6f7420626520756e64656c6567617465640000006064820152608401610b31565b6001600160a01b03831661234b5760405162461bcd60e51b815260206004820152603c60248201527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a20636160448201527f6e6e6f7420756e64656c6567617465207a65726f2061646472657373000000006064820152608401610b31565b6001600160a01b038084166000818152609a60205260409020549091169033148061237e5750336001600160a01b038216145b806123a557506001600160a01b038181166000908152609960205260409020600101541633145b6124175760405162461bcd60e51b815260206004820152603d60248201527f44656c65676174696f6e4d616e616765722e756e64656c65676174653a20636160448201527f6c6c65722063616e6e6f7420756e64656c6567617465207374616b65720000006064820152608401610b31565b60008061242386611de6565b9092509050336001600160a01b0387161461247957826001600160a01b0316866001600160a01b03167ff0eddf07e6ea14f388b47e1e94a0f464ecbd9eed4171130e0fc0e99fb4030a8a60405160405180910390a35b826001600160a01b0316866001600160a01b03167ffee30966a256b71e14bc0ebfc94315e28ef4a97a7131a9e2b7a310a73af4467660405160405180910390a36001600160a01b0386166000908152609a6020526040902080546001600160a01b031916905581516124fb576040805160008152602081019091529450612659565b81516001600160401b0381111561251457612514614ebe565b60405190808252806020026020018201604052801561253d578160200160208202803683370190505b50945060005b8251811015612657576040805160018082528183019092526000916020808301908036833750506040805160018082528183019092529293506000929150602080830190803683370190505090508483815181106125a3576125a3615765565b6020026020010151826000815181106125be576125be615765565b60200260200101906001600160a01b031690816001600160a01b0316815250508383815181106125f0576125f0615765565b60200260200101518160008151811061260b5761260b615765565b60200260200101818152505061262489878b858561290f565b88848151811061263657612636615765565b6020026020010181815250505050808061264f90615791565b915050612543565b505b50505050919050565b6111233384848461316b565b61267733611a48565b6126f55760405162461bcd60e51b815260206004820152604360248201527f44656c65676174696f6e4d616e616765722e6d6f646966794f70657261746f7260448201527f44657461696c733a2063616c6c6572206d75737420626520616e206f706572616064820152623a37b960e91b608482015260a401610b31565b61106e3382612ecf565b612707613682565b6001600160a01b03811661276c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b31565b61106e81613a7f565b60007f0000000000000000000000000000000000000000000000000000000000007a694614156127a6575060975490565b6127ae6139e8565b905090565b606560009054906101000a90046001600160a01b03166001600160a01b031663eab66d7a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612806573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061282a91906158cd565b6001600160a01b0316336001600160a01b03161461285a5760405162461bcd60e51b8152600401610b31906158ea565b6066541981196066541916146128d85760405162461bcd60e51b815260206004820152603860248201527f5061757361626c652e756e70617573653a20696e76616c696420617474656d7060448201527f7420746f2070617573652066756e6374696f6e616c69747900000000000000006064820152608401610b31565b606681905560405181815233907f3582d1828e26bf56bd801502bc021ac0bc8afb57c826e4986b45593c8fad389c9060200161125c565b60006001600160a01b0386166129a65760405162461bcd60e51b815260206004820152605060248201527f44656c65676174696f6e4d616e616765722e5f72656d6f76655368617265734160448201527f6e6451756575655769746864726177616c3a207374616b65722063616e6e6f7460648201526f206265207a65726f206164647265737360801b608482015260a401610b31565b8251612a305760405162461bcd60e51b815260206004820152604d60248201527f44656c65676174696f6e4d616e616765722e5f72656d6f76655368617265734160448201527f6e6451756575655769746864726177616c3a207374726174656769657320636160648201526c6e6e6f7420626520656d70747960981b608482015260a401610b31565b60005b8351811015612ddd576001600160a01b03861615612a8957612a898688868481518110612a6257612a62615765565b6020026020010151868581518110612a7c57612a7c615765565b6020026020010151613607565b73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06001600160a01b0316848281518110612ab957612ab9615765565b60200260200101516001600160a01b03161415612b82577f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c8536001600160a01b031663beffbb8988858481518110612b1257612b12615765565b60200260200101516040518363ffffffff1660e01b8152600401612b4b9291906001600160a01b03929092168252602082015260400190565b600060405180830381600087803b158015612b6557600080fd5b505af1158015612b79573d6000803e3d6000fd5b50505050612dd5565b846001600160a01b0316876001600160a01b03161480612c5457507f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c96001600160a01b0316639b4da03d858381518110612bde57612bde615765565b60200260200101516040518263ffffffff1660e01b8152600401612c1191906001600160a01b0391909116815260200190565b602060405180830381865afa158015612c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c529190615991565b155b612d205760405162461bcd60e51b8152602060048201526084602482018190527f44656c65676174696f6e4d616e616765722e5f72656d6f76655368617265734160448301527f6e6451756575655769746864726177616c3a2077697468647261776572206d7560648301527f73742062652073616d652061646472657373206173207374616b657220696620908201527f746869726450617274795472616e7366657273466f7262696464656e2061726560a482015263081cd95d60e21b60c482015260e401610b31565b7f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c96001600160a01b0316638c80d4e588868481518110612d6257612d62615765565b6020026020010151868581518110612d7c57612d7c615765565b60200260200101516040518463ffffffff1660e01b8152600401612da293929190615d00565b600060405180830381600087803b158015612dbc57600080fd5b505af1158015612dd0573d6000803e3d6000fd5b505050505b600101612a33565b506001600160a01b0386166000908152609f60205260408120805491829190612e0583615791565b919050555060006040518060e00160405280896001600160a01b03168152602001886001600160a01b03168152602001876001600160a01b031681526020018381526020014363ffffffff1681526020018681526020018581525090506000612e6d826116c1565b6000818152609e602052604090819020805460ff19166001179055519091507f9009ab153e8014fbfb02f2217f5cde7aa7f9ad734ae85ca3ee3f4ca2fdd499f990612ebb9083908590615b8a565b60405180910390a198975050505050505050565b6000612ede6020830183614c8c565b6001600160a01b03161415612f785760405162461bcd60e51b815260206004820152605460248201527f44656c65676174696f6e4d616e616765722e5f7365744f70657261746f72446560448201527f7461696c733a2063616e6e6f742073657420606561726e696e677352656365696064820152737665726020746f207a65726f206164647265737360601b608482015260a401610b31565b6213c680612f8c6060830160408401615d24565b63ffffffff1611156130415760405162461bcd60e51b815260206004820152606c60248201527f44656c65676174696f6e4d616e616765722e5f7365744f70657261746f72446560448201527f7461696c733a207374616b65724f70744f757457696e646f77426c6f636b732060648201527f63616e6e6f74206265203e204d41585f5354414b45525f4f50545f4f55545f5760848201526b494e444f575f424c4f434b5360a01b60a482015260c401610b31565b6001600160a01b0382166000908152609960205260409081902060010154600160a01b900463ffffffff169061307d9060608401908401615d24565b63ffffffff1610156131135760405162461bcd60e51b815260206004820152605360248201527f44656c65676174696f6e4d616e616765722e5f7365744f70657261746f72446560448201527f7461696c733a207374616b65724f70744f757457696e646f77426c6f636b732060648201527218d85b9b9bdd08189948191958dc99585cd959606a1b608482015260a401610b31565b6001600160a01b038216600090815260996020526040902081906131378282615d61565b505060405133907ffebe5cd24b2cbc7b065b9d0fdeb904461e4afcff57dd57acda1e7832031ba7ac90611d2190849061584c565b606654600090600190811614156131945760405162461bcd60e51b8152600401610b31906157ac565b61319d856115da565b1561321a5760405162461bcd60e51b815260206004820152604160248201527f44656c65676174696f6e4d616e616765722e5f64656c65676174653a2073746160448201527f6b657220697320616c7265616479206163746976656c792064656c65676174656064820152601960fa1b608482015260a401610b31565b61322384611a48565b6132a35760405162461bcd60e51b815260206004820152604560248201527f44656c65676174696f6e4d616e616765722e5f64656c65676174653a206f706560448201527f7261746f72206973206e6f74207265676973746572656420696e20456967656e6064820152642630bcb2b960d91b608482015260a401610b31565b6001600160a01b038085166000908152609960205260409020600101541680158015906132d95750336001600160a01b03821614155b80156132ee5750336001600160a01b03861614155b1561345b57428460200151101561336d5760405162461bcd60e51b815260206004820152603760248201527f44656c65676174696f6e4d616e616765722e5f64656c65676174653a2061707060448201527f726f766572207369676e617475726520657870697265640000000000000000006064820152608401610b31565b6001600160a01b0381166000908152609c6020908152604080832086845290915290205460ff16156134075760405162461bcd60e51b815260206004820152603760248201527f44656c65676174696f6e4d616e616765722e5f64656c65676174653a2061707060448201527f726f76657253616c7420616c7265616479207370656e740000000000000000006064820152608401610b31565b6001600160a01b0381166000908152609c6020908152604080832086845282528220805460ff19166001179055850151613448908890889085908890610a43565b905061345982828760000151614430565b505b6001600160a01b038681166000818152609a602052604080822080546001600160a01b031916948a169485179055517fc3ee9f2e5fda98e8066a1f745b2df9285f416fe98cf2559cd21484b3d87433049190a36000806134ba88611de6565b9150915060005b82518110156113e257613508888a8584815181106134e1576134e1615765565b60200260200101518585815181106134fb576134fb615765565b6020026020010151613bcb565b6001016134c1565b6001600160a01b03811661359e5760405162461bcd60e51b815260206004820152604960248201527f5061757361626c652e5f73657450617573657252656769737472793a206e657760448201527f50617573657252656769737472792063616e6e6f7420626520746865207a65726064820152686f206164647265737360b81b608482015260a401610b31565b606554604080516001600160a01b03928316815291831660208301527f6e9fcd539896fca60e8b0f01dd580233e48a6b0f7df013b89ba7f565869acdb6910160405180910390a1606580546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0380851660009081526098602090815260408083209386168352929052908120805483929061363e908490615ce9565b92505081905550836001600160a01b03167f6909600037b75d7b4733aedd815442b5ec018a827751c832aaff64eba5d6d2dd848484604051610fb093929190615d00565b6033546001600160a01b03163314611a7a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b31565b8281146137645760405162461bcd60e51b815260206004820152604a60248201527f44656c65676174696f6e4d616e616765722e5f7365745374726174656779576960448201527f746864726177616c44656c6179426c6f636b733a20696e707574206c656e67746064820152690d040dad2e6dac2e8c6d60b31b608482015260a401610b31565b8260005b818110156138fa57600086868381811061378457613784615765565b90506020020160208101906137999190614c8c565b6001600160a01b038116600090815260a160205260408120549192508686858181106137c7576137c7615765565b90506020020135905062034bc081111561388b5760405162461bcd60e51b815260206004820152607360248201527f44656c65676174696f6e4d616e616765722e5f7365745374726174656779576960448201527f746864726177616c44656c6179426c6f636b733a205f7769746864726177616c60648201527f44656c6179426c6f636b732063616e6e6f74206265203e204d41585f5749544860848201527244524157414c5f44454c41595f424c4f434b5360681b60a482015260c401610b31565b6001600160a01b038316600081815260a160209081526040918290208490558151928352820184905281018290527f0e7efa738e8b0ce6376a0c1af471655540d2e9a81647d7b09ed823018426576d9060600160405180910390a1505050806138f390615791565b9050613768565b505050505050565b6065546001600160a01b031615801561392357506001600160a01b03821615155b6139a55760405162461bcd60e51b815260206004820152604760248201527f5061757361626c652e5f696e697469616c697a655061757365723a205f696e6960448201527f7469616c697a6550617573657228292063616e206f6e6c792062652063616c6c6064820152666564206f6e636560c81b608482015260a401610b31565b606681905560405181815233907fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d9060200160405180910390a261199882613510565b604080518082018252600a81526922b4b3b2b72630bcb2b960b11b60209182015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866818301527f71b625cfad44bac63b13dba07f2e1d6084ee04b6f8752101ece6126d584ee6ea81840152466060820152306080808301919091528351808303909101815260a0909101909252815191012090565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b62034bc0811115613b8a5760405162461bcd60e51b815260206004820152607160248201527f44656c65676174696f6e4d616e616765722e5f7365744d696e5769746864726160448201527f77616c44656c6179426c6f636b733a205f6d696e5769746864726177616c446560648201527f6c6179426c6f636b732063616e6e6f74206265203e204d41585f5749544844526084820152704157414c5f44454c41595f424c4f434b5360781b60a482015260c401610b31565b609d5460408051918252602082018390527fafa003cd76f87ff9d62b35beea889920f33c0c42b8d45b74954d61d50f4b6b69910160405180910390a1609d55565b6001600160a01b03808516600090815260986020908152604080832093861683529290529081208054839290613c02908490615cd1565b92505081905550836001600160a01b03167f1ec042c965e2edd7107b51188ee0f383e22e76179041ab3a9d18ff151405166c848484604051610fb093929190615d00565b6000613c5461062987615dc4565b6000818152609e602052604090205490915060ff16613cd55760405162461bcd60e51b81526020600482015260436024820152600080516020615efc83398151915260448201527f645769746864726177616c3a20616374696f6e206973206e6f7420696e20717560648201526265756560e81b608482015260a401610b31565b609d544390613cea60a0890160808a01615d24565b63ffffffff16613cfa9190615cd1565b1115613d825760405162461bcd60e51b815260206004820152605f6024820152600080516020615efc83398151915260448201527f645769746864726177616c3a206d696e5769746864726177616c44656c61794260648201527f6c6f636b7320706572696f6420686173206e6f74207965742070617373656400608482015260a401610b31565b613d926060870160408801614c8c565b6001600160a01b0316336001600160a01b031614613e1f5760405162461bcd60e51b81526020600482015260506024820152600080516020615efc83398151915260448201527f645769746864726177616c3a206f6e6c7920776974686472617765722063616e60648201526f1031b7b6b83632ba329030b1ba34b7b760811b608482015260a401610b31565b8115613ea157613e3260a0870187615803565b85149050613ea15760405162461bcd60e51b81526020600482015260426024820152600080516020615efc83398151915260448201527f645769746864726177616c3a20696e707574206c656e677468206d69736d61746064820152610c6d60f31b608482015260a401610b31565b6000818152609e60205260409020805460ff1916905581156140065760005b613ecd60a0880188615803565b9050811015614000574360a16000613ee860a08b018b615803565b85818110613ef857613ef8615765565b9050602002016020810190613f0d9190614c8c565b6001600160a01b03168152602081019190915260400160002054613f3760a08a0160808b01615d24565b63ffffffff16613f479190615cd1565b1115613f655760405162461bcd60e51b8152600401610b3190615dd6565b613ff8613f756020890189614c8c565b33613f8360a08b018b615803565b85818110613f9357613f93615765565b9050602002016020810190613fa89190614c8c565b613fb560c08c018c615803565b86818110613fc557613fc5615765565b905060200201358a8a87818110613fde57613fde615765565b9050602002016020810190613ff39190614c8c565b6145ea565b600101613ec0565b506143f5565b336000908152609a60205260408120546001600160a01b0316905b61402e60a0890189615803565b90508110156143f2574360a1600061404960a08c018c615803565b8581811061405957614059615765565b905060200201602081019061406e9190614c8c565b6001600160a01b0316815260208101919091526040016000205461409860a08b0160808c01615d24565b63ffffffff166140a89190615cd1565b11156140c65760405162461bcd60e51b8152600401610b3190615dd6565b73beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac06140e860a08a018a615803565b838181106140f8576140f8615765565b905060200201602081019061410d9190614c8c565b6001600160a01b0316141561425d57600061412b60208a018a614c8c565b905060006001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c85316630e81073c8361416c60c08e018e615803565b8781811061417c5761417c615765565b6040516001600160e01b031960e087901b1681526001600160a01b03909416600485015260200291909101356024830152506044016020604051808303816000875af11580156141d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141f49190615ba3565b6001600160a01b038084166000908152609a602052604090205491925016801561425557614255818461422a60a08f018f615803565b8881811061423a5761423a615765565b905060200201602081019061424f9190614c8c565b85613bcb565b5050506143ea565b7f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c96001600160a01b031663c4623ea13389898581811061429f5761429f615765565b90506020020160208101906142b49190614c8c565b6142c160a08d018d615803565b868181106142d1576142d1615765565b90506020020160208101906142e69190614c8c565b6142f360c08e018e615803565b8781811061430357614303615765565b60405160e088901b6001600160e01b03191681526001600160a01b03968716600482015294861660248601529290941660448401526020909102013560648201526084019050600060405180830381600087803b15801561436357600080fd5b505af1158015614377573d6000803e3d6000fd5b505050506001600160a01b038216156143ea576143ea823361439c60a08c018c615803565b858181106143ac576143ac615765565b90506020020160208101906143c19190614c8c565b6143ce60c08d018d615803565b868181106143de576143de615765565b90506020020135613bcb565b600101614021565b50505b6040518181527fc97098c2f658800b4df29001527f7324bcdffcf6e8751a699ab920a1eced5b1d9060200160405180910390a1505050505050565b6001600160a01b0383163b1561454a57604051630b135d3f60e11b808252906001600160a01b03851690631626ba7e906144709086908690600401615e5e565b602060405180830381865afa15801561448d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144b19190615ebb565b6001600160e01b031916146111235760405162461bcd60e51b815260206004820152605360248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a2045524331323731207369676e6174757265206064820152721d995c9a599a58d85d1a5bdb8819985a5b1959606a1b608482015260a401610b31565b826001600160a01b031661455e838361472a565b6001600160a01b0316146111235760405162461bcd60e51b815260206004820152604760248201527f454950313237315369676e61747572655574696c732e636865636b5369676e6160448201527f747572655f454950313237313a207369676e6174757265206e6f742066726f6d6064820152661039b4b3b732b960c91b608482015260a401610b31565b6001600160a01b03831673beac0eeeeeeeeeeeeeeeeeeeeeeeeeeeeeebeac014156146955760405162387b1360e81b81526001600160a01b037f000000000000000000000000a513e6e4b8f2a923d98304ec87f64353c4d5c853169063387b13009061465e90889088908790600401615d00565b600060405180830381600087803b15801561467857600080fd5b505af115801561468c573d6000803e3d6000fd5b50505050614723565b60405163c608c7f360e01b81526001600160a01b03858116600483015284811660248301526044820184905282811660648301527f000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c9169063c608c7f390608401600060405180830381600087803b15801561470f57600080fd5b505af11580156113e2573d6000803e3d6000fd5b5050505050565b60008060006147398585614746565b91509150610a3b816147b6565b60008082516041141561477d5760208301516040840151606085015160001a61477187828585614971565b945094505050506147af565b8251604014156147a7576020830151604084015161479c868383614a5e565b9350935050506147af565b506000905060025b9250929050565b60008160048111156147ca576147ca615ee5565b14156147d35750565b60018160048111156147e7576147e7615ee5565b14156148355760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610b31565b600281600481111561484957614849615ee5565b14156148975760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610b31565b60038160048111156148ab576148ab615ee5565b14156149045760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610b31565b600481600481111561491857614918615ee5565b141561106e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610b31565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156149a85750600090506003614a55565b8460ff16601b141580156149c057508460ff16601c14155b156149d15750600090506004614a55565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614a25573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116614a4e57600060019250925050614a55565b9150600090505b94509492505050565b6000806001600160ff1b03831681614a7b60ff86901c601b615cd1565b9050614a8987828885614971565b935093505050935093915050565b60008083601f840112614aa957600080fd5b5081356001600160401b03811115614ac057600080fd5b6020830191508360208260051b85010111156147af57600080fd5b60008060208385031215614aee57600080fd5b82356001600160401b03811115614b0457600080fd5b614b1085828601614a97565b90969095509350505050565b6001600160a01b038116811461106e57600080fd5b8035614b3c81614b1c565b919050565b600080600080600060a08688031215614b5957600080fd5b8535614b6481614b1c565b94506020860135614b7481614b1c565b93506040860135614b8481614b1c565b94979396509394606081013594506080013592915050565b6020808252825182820181905260009190848201906040850190845b81811015614bd457835183529284019291840191600101614bb8565b50909695505050505050565b600060608284031215614bf257600080fd5b50919050565b60008083601f840112614c0a57600080fd5b5081356001600160401b03811115614c2157600080fd5b6020830191508360208285010111156147af57600080fd5b600080600060808486031215614c4e57600080fd5b614c588585614be0565b925060608401356001600160401b03811115614c7357600080fd5b614c7f86828701614bf8565b9497909650939450505050565b600060208284031215614c9e57600080fd5b8135614ca981614b1c565b9392505050565b600080600060608486031215614cc557600080fd5b8335614cd081614b1c565b92506020840135614ce081614b1c565b929592945050506040919091013590565b600060208284031215614d0357600080fd5b5035919050565b60008060008060408587031215614d2057600080fd5b84356001600160401b0380821115614d3757600080fd5b614d4388838901614a97565b90965094506020870135915080821115614d5c57600080fd5b50614d6987828801614a97565b95989497509550505050565b60008060008060008060008060c0898b031215614d9157600080fd5b8835614d9c81614b1c565b97506020890135614dac81614b1c565b9650604089013595506060890135945060808901356001600160401b0380821115614dd657600080fd5b614de28c838d01614a97565b909650945060a08b0135915080821115614dfb57600080fd5b50614e088b828c01614a97565b999c989b5096995094979396929594505050565b6000806000806000806000806080898b031215614e3857600080fd5b88356001600160401b0380821115614e4f57600080fd5b614e5b8c838d01614a97565b909a50985060208b0135915080821115614e7457600080fd5b614e808c838d01614a97565b909850965060408b0135915080821115614e9957600080fd5b614ea58c838d01614a97565b909650945060608b0135915080821115614dfb57600080fd5b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b0381118282101715614ef657614ef6614ebe565b60405290565b604080519081016001600160401b0381118282101715614ef657614ef6614ebe565b60405160c081016001600160401b0381118282101715614ef657614ef6614ebe565b604051601f8201601f191681016001600160401b0381118282101715614f6857614f68614ebe565b604052919050565b63ffffffff8116811461106e57600080fd5b8035614b3c81614f70565b60006001600160401b03821115614fa657614fa6614ebe565b5060051b60200190565b600082601f830112614fc157600080fd5b81356020614fd6614fd183614f8d565b614f40565b82815260059290921b84018101918181019086841115614ff557600080fd5b8286015b8481101561501957803561500c81614b1c565b8352918301918301614ff9565b509695505050505050565b600082601f83011261503557600080fd5b81356020615045614fd183614f8d565b82815260059290921b8401810191818101908684111561506457600080fd5b8286015b848110156150195780358352918301918301615068565b600060e0828403121561509157600080fd5b615099614ed4565b90506150a482614b31565b81526150b260208301614b31565b60208201526150c360408301614b31565b6040820152606082013560608201526150de60808301614f82565b608082015260a08201356001600160401b03808211156150fd57600080fd5b61510985838601614fb0565b60a084015260c084013591508082111561512257600080fd5b5061512f84828501615024565b60c08301525092915050565b60006020828403121561514d57600080fd5b81356001600160401b0381111561516357600080fd5b61516f8482850161507f565b949350505050565b60006020828403121561518957600080fd5b813560ff81168114614ca957600080fd5b6000604082840312156151ac57600080fd5b6151b4614efc565b905081356151c181614b1c565b815260208201356bffffffffffffffffffffffff811681146151e257600080fd5b602082015292915050565b6000602080838503121561520057600080fd5b82356001600160401b038082111561521757600080fd5b818501915085601f83011261522b57600080fd5b8135615239614fd182614f8d565b81815260059190911b8301840190848101908883111561525857600080fd5b8585015b83811015615332578035858111156152745760008081fd5b860160e0818c03601f190181131561528c5760008081fd5b615294614f1e565b89830135888111156152a65760008081fd5b6152b48e8c83870101614fb0565b825250604080840135898111156152cb5760008081fd5b6152d98f8d83880101615024565b8c8401525060606152eb818601614b31565b82840152608091506152ff8f83870161519a565b9083015261530f60c08501614f82565b9082015261531e838301614b31565b60a08201528552505091860191860161525c565b5098975050505050505050565b801515811461106e57600080fd5b60008060008060006080868803121561536557600080fd5b85356001600160401b038082111561537c57600080fd5b9087019060e0828a03121561539057600080fd5b909550602087013590808211156153a657600080fd5b506153b388828901614a97565b9095509350506040860135915060608601356153ce8161533f565b809150509295509295909350565b600080604083850312156153ef57600080fd5b82356153fa81614b1c565b9150602083013561540a81614b1c565b809150509250929050565b60006040828403121561542757600080fd5b61542f614efc565b905081356001600160401b038082111561544857600080fd5b818401915084601f83011261545c57600080fd5b813560208282111561547057615470614ebe565b615482601f8301601f19168201614f40565b9250818352868183860101111561549857600080fd5b8181850182850137600081838501015282855280860135818601525050505092915050565b600080600080600060a086880312156154d557600080fd5b85356154e081614b1c565b945060208601356154f081614b1c565b935060408601356001600160401b038082111561550c57600080fd5b61551889838a01615415565b9450606088013591508082111561552e57600080fd5b5061553b88828901615415565b95989497509295608001359392505050565b6000806040838503121561556057600080fd5b823561556b81614b1c565b915060208301356001600160401b0381111561558657600080fd5b61559285828601614fb0565b9150509250929050565b600081518084526020808501945080840160005b838110156155cc578151875295820195908201906001016155b0565b509495945050505050565b602081526000614ca9602083018461559c565b600080602083850312156155fd57600080fd5b82356001600160401b0381111561561357600080fd5b614b1085828601614bf8565b6000806040838503121561563257600080fd5b823561563d81614b1c565b946020939093013593505050565b6000806000806080858703121561566157600080fd5b843561566c81614b1c565b935060208501359250604085013561568381614b1c565b9396929550929360600135925050565b600081518084526020808501945080840160005b838110156155cc5781516001600160a01b0316875295820195908201906001016156a7565b6040815260006156df6040830185615693565b82810360208401526112a0818561559c565b60008060006060848603121561570657600080fd5b833561571181614b1c565b925060208401356001600160401b0381111561572c57600080fd5b61573886828701615415565b925050604084013590509250925092565b60006060828403121561575b57600080fd5b614ca98383614be0565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156157a5576157a561577b565b5060010190565b60208082526019908201527f5061757361626c653a20696e6465782069732070617573656400000000000000604082015260600190565b60008235605e198336030181126157f957600080fd5b9190910192915050565b6000808335601e1984360301811261581a57600080fd5b8301803591506001600160401b0382111561583457600080fd5b6020019150600581901b36038213156147af57600080fd5b60608101823561585b81614b1c565b6001600160a01b03908116835260208401359061587782614b1c565b166020830152604083013561588b81614f70565b63ffffffff811660408401525092915050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b6000602082840312156158df57600080fd5b8151614ca981614b1c565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b606082015260800190565b60208082526037908201527f44656c65676174696f6e4d616e616765723a206f6e6c7953747261746567794d60408201527f616e616765724f72456967656e506f644d616e61676572000000000000000000606082015260800190565b6000602082840312156159a357600080fd5b8151614ca98161533f565b60208082526028908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526739903830bab9b2b960c11b606082015260800190565b6000823560de198336030181126157f957600080fd5b600060208284031215615a1e57600080fd5b8135614ca98161533f565b600060018060a01b03808351168452806020840151166020850152806040840151166040850152506060820151606084015263ffffffff608083015116608084015260a082015160e060a0850152615a8460e0850182615693565b905060c083015184820360c08601526112a0828261559c565b602081526000614ca96020830184615a29565b602081526000825160e06020840152615acd610100840182615693565b90506020840151601f19848303016040850152615aea828261559c565b915050604084015160018060a01b03808216606086015260608601519150808251166080860152506bffffffffffffffffffffffff60208201511660a0850152506080840151615b4260c085018263ffffffff169052565b5060a08401516001600160a01b03811660e0850152610a3b565b60008060408385031215615b6f57600080fd5b8251615b7a8161533f565b6020939093015192949293505050565b82815260406020820152600061516f6040830184615a29565b600060208284031215615bb557600080fd5b5051919050565b600082601f830112615bcd57600080fd5b81516020615bdd614fd183614f8d565b82815260059290921b84018101918181019086841115615bfc57600080fd5b8286015b848110156150195780518352918301918301615c00565b60008060408385031215615c2a57600080fd5b82516001600160401b0380821115615c4157600080fd5b818501915085601f830112615c5557600080fd5b81516020615c65614fd183614f8d565b82815260059290921b84018101918181019089841115615c8457600080fd5b948201945b83861015615cab578551615c9c81614b1c565b82529482019490820190615c89565b91880151919650909350505080821115615cc457600080fd5b5061559285828601615bbc565b60008219821115615ce457615ce461577b565b500190565b600082821015615cfb57615cfb61577b565b500390565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600060208284031215615d3657600080fd5b8135614ca981614f70565b80546001600160a01b0319166001600160a01b0392909216919091179055565b8135615d6c81614b1c565b615d768183615d41565b50600181016020830135615d8981614b1c565b615d938183615d41565b506040830135615da281614f70565b815463ffffffff60a01b191660a09190911b63ffffffff60a01b161790555050565b6000615dd0368361507f565b92915050565b6020808252606e90820152600080516020615efc83398151915260408201527f645769746864726177616c3a207769746864726177616c44656c6179426c6f6360608201527f6b7320706572696f6420686173206e6f74207965742070617373656420666f7260808201526d207468697320737472617465677960901b60a082015260c00190565b82815260006020604081840152835180604085015260005b81811015615e9257858101830151858201606001528201615e76565b81811115615ea4576000606083870101525b50601f01601f191692909201606001949350505050565b600060208284031215615ecd57600080fd5b81516001600160e01b031981168114614ca957600080fd5b634e487b7160e01b600052602160045260246000fdfe44656c65676174696f6e4d616e616765722e5f636f6d706c6574655175657565a2646970667358221220794b5c92c2b133ceda4be4341515834a97d52b26b6cf257dc5a843057bc3a70164736f6c634300080c0033","storage":{"0x0":"0xff"}},"0xcf7ed3acca5a467e9e704c703e8d87f634fb0fc9":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033","storage":{"0x0":"0x1","0x33":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x65":"0xe7f1725e7734ce288f8367e1bb143e90bb3f0512","0x66":"0x0","0x97":"0x831f01b2aeb61d5d8c019704e62c25763057a8806c5c790bc8b4c99ee54ac8a7","0x9d":"0x1","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0xb7f8bc63bbcad18155201308c8f3540b07f84f5e","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0xdc64a140aa3e981100a9beca4e685f962f0cf6c9":{"nonce":1,"balance":"0x0","code":"0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033","storage":{"0x0":"0x1","0x33":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x97":"0xe7f1725e7734ce288f8367e1bb143e90bb3f0512","0x98":"0x0","0xc9":"0xd65ac9700cec4e530497617d02afdf0d5de3ed18466aca1578edcbce0d40ee16","0xcb":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc":"0xa51c1fc2f0d1a1b8494ed1fe312d7c3a78ed91c0","0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103":"0x5fbdb2315678afecb367f032d93f642f64180aa3"}},"0xe7f1725e7734ce288f8367e1bb143e90bb3f0512":{"nonce":1,"balance":"0x0","code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806346fbf68e146100515780638568520614610089578063ce5484281461009e578063eab66d7a146100b1575b600080fd5b61007461005f366004610313565b60006020819052908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61009c610097366004610335565b6100dc565b005b61009c6100ac366004610313565b61011d565b6001546100c4906001600160a01b031681565b6040516001600160a01b039091168152602001610080565b6001546001600160a01b0316331461010f5760405162461bcd60e51b815260040161010690610371565b60405180910390fd5b6101198282610153565b5050565b6001546001600160a01b031633146101475760405162461bcd60e51b815260040161010690610371565b61015081610220565b50565b6001600160a01b0382166101bf5760405162461bcd60e51b815260206004820152602d60248201527f50617573657252656769737472792e5f7365745061757365723a207a65726f2060448201526c1859191c995cdcc81a5b9c1d5d609a1b6064820152608401610106565b6001600160a01b03821660008181526020818152604091829020805460ff19168515159081179091558251938452908301527f65d3a1fd4c13f05cba164f80d03ce90fb4b5e21946bfc3ab7dbd434c2d0b9152910160405180910390a15050565b6001600160a01b03811661028e5760405162461bcd60e51b815260206004820152602f60248201527f50617573657252656769737472792e5f736574556e7061757365723a207a657260448201526e1bc81859191c995cdcc81a5b9c1d5d608a1b6064820152608401610106565b600154604080516001600160a01b03928316815291831660208301527f06b4167a2528887a1e97a366eefe8549bfbf1ea3e6ac81cb2564a934d20e8892910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160a01b038116811461030e57600080fd5b919050565b60006020828403121561032557600080fd5b61032e826102f7565b9392505050565b6000806040838503121561034857600080fd5b610351836102f7565b91506020830135801515811461036657600080fd5b809150509250929050565b6020808252602a908201527f6d73672e73656e646572206973206e6f74207065726d697373696f6e6564206160408201526939903ab73830bab9b2b960b11b60608201526080019056fea264697066735822122082c17cbba412d9a44621d8a07946e79322d6248e2e7c652573dcc2c61babeb8c64736f6c634300080c0033","storage":{"0x1":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","0x723077b8a1b173adc35e5f0e7e3662fd1208212cb629f9c128551ea7168da722":"0x1"}},"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266":{"nonce":26,"balance":"0x21e1993a279b12a6826","code":"0x","storage":{}}}} \ No newline at end of file diff --git a/temp-incredible-squaring-avs/tests/anvil/genesis.json b/temp-incredible-squaring-avs/tests/anvil/genesis.json new file mode 100644 index 0000000..e47134d --- /dev/null +++ b/temp-incredible-squaring-avs/tests/anvil/genesis.json @@ -0,0 +1,49 @@ +{ + "nonce": "0x0", + "timestamp": "0x0", + "extraData": "0x5343", + "gasLimit": "0x1388", + "difficulty": "0x400000000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "0xd143C405751162d0F96bEE2eB5eb9C61882a736E": { + "balance": "0x4a47e3c12448f4ad000000" + }, + "0x0165878a594ca255338adfa4d48449f69242eb8f": { + "nonce": 1, + "balance": "0x0", + "code": "0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106f1565b610118565b61005b61009336600461070c565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106f1565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b6060610285838360405180606001604052806027815260200161080b6027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f7565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051f565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a16101548161055f565b60606001600160a01b0384163b6104825760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610331565b600080856001600160a01b03168560405161049d91906107bb565b600060405180830381855af49150503d80600081146104d8576040519150601f19603f3d011682016040523d82523d6000602084013e6104dd565b606091505b50915091506104ed828286610608565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b61052881610641565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105c45760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60608315610617575081610285565b8251156106275782518084602001fd5b8160405162461bcd60e51b815260040161033191906107d7565b6001600160a01b0381163b6106ae5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105e7565b80356001600160a01b03811681146106ec57600080fd5b919050565b60006020828403121561070357600080fd5b610285826106d5565b60008060006040848603121561072157600080fd5b61072a846106d5565b9250602084013567ffffffffffffffff8082111561074757600080fd5b818601915086601f83011261075b57600080fd5b81358181111561076a57600080fd5b87602082850101111561077c57600080fd5b6020830194508093505050509250925092565b60005b838110156107aa578181015183820152602001610792565b838111156103c05750506000910152565b600082516107cd81846020870161078f565b9190910192915050565b60208152600082518060208401526107f681604085016020870161078f565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220bceca38d0e447b38e612e8ea5bb02b1e1fcac6609b19aa0fd3fd43aa4b97bf1b64736f6c634300080c0033", + "storage": { + "0x0": "0x1", + "0x33": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "0x65": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "0x66": "0x1e", + "0x97": "0x0", + "0x9a": "0x0", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0xdcd1bf9a1b36ce34237eeafef220932846bcd82", + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x5fbdb2315678afecb367f032d93f642f64180aa3" + } + } + }, + "number": "7", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "config": { + "ethash": {}, + "chainId": 31337, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "terminalTotalDifficulty": 0, + "terminalTotalDifficultyPassed": true, + "shanghaiTime": 0 + } +} diff --git a/temp-incredible-squaring-avs/tests/anvil/operator-registration.sh b/temp-incredible-squaring-avs/tests/anvil/operator-registration.sh new file mode 100755 index 0000000..9b313fd --- /dev/null +++ b/temp-incredible-squaring-avs/tests/anvil/operator-registration.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +cd ../../ && make cli-setup-operator \ No newline at end of file diff --git a/temp-incredible-squaring-avs/tests/anvil/start-anvil-chain-with-el-and-avs-deployed.sh b/temp-incredible-squaring-avs/tests/anvil/start-anvil-chain-with-el-and-avs-deployed.sh new file mode 100755 index 0000000..85033db --- /dev/null +++ b/temp-incredible-squaring-avs/tests/anvil/start-anvil-chain-with-el-and-avs-deployed.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +RPC_URL=http://localhost:8545 + +# cd to the directory of this script so that this can be run from anywhere +parent_path=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + pwd -P +) +cd "$parent_path" + +set -a +source ./utils.sh +set +a + +cleanup() { + echo "Executing cleanup function..." + set +e + docker rm -f anvil + exit_status=$? + if [ $exit_status -ne 0 ]; then + echo "Script exited due to set -e on line $1 with command '$2'. Exit status: $exit_status" + fi +} +trap 'cleanup $LINENO "$BASH_COMMAND"' EXIT + +# start an anvil instance in the background that has eigenlayer contracts deployed +# we start anvil in the background so that we can run the below script +# anvil --load-state avs-and-eigenlayer-deployed-anvil-state.json & +# FIXME: bug in latest foundry version, so we use this pinned version instead of latest +start_anvil_docker $parent_path/avs-and-eigenlayer-deployed-anvil-state.json "" + +cd ../../contracts +# we need to restart the anvil chain at the correct block, otherwise the indexRegistry has a quorumUpdate at the block number +# at which it was deployed (aka quorum was created/updated), but when we start anvil by loading state file it starts at block number 0 +# so calling getOperatorListAtBlockNumber reverts because it thinks there are no quorums registered at block 0 +# advancing chain manually like this is a current hack until https://github.com/foundry-rs/foundry/issues/6679 is merged +cast rpc anvil_mine 100 --rpc-url $RPC_URL +echo "advancing chain... current block-number:" $(cast block-number) + +# Bring Anvil back to the foreground +docker attach anvil diff --git a/temp-incredible-squaring-avs/tests/anvil/utils.sh b/temp-incredible-squaring-avs/tests/anvil/utils.sh new file mode 100644 index 0000000..84184e3 --- /dev/null +++ b/temp-incredible-squaring-avs/tests/anvil/utils.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +set -e -o nounset + +# pinning at old foundry commit because of https://github.com/foundry-rs/foundry/issues/7502 +FOUNDRY_IMAGE=ghcr.io/foundry-rs/foundry:nightly-5b7e4cb3c882b28f3c32ba580de27ce7381f415a + +parent_path=$( + cd "$(dirname "${BASH_SOURCE[0]}")" + pwd -P +) + +clean_up() { + # Check if the exit status is non-zero + exit_status=$? + if [ $exit_status -ne 0 ]; then + echo "Script exited due to set -e on line $1 with command '$2'. Exit status: $exit_status" + fi +} +# Use trap to call the clean_up function when the script exits +trap 'clean_up $LINENO "$BASH_COMMAND"' ERR + +# start_anvil_docker $LOAD_STATE_FILE $DUMP_STATE_FILE +start_anvil_docker() { + LOAD_STATE_FILE=$1 + DUMP_STATE_FILE=$2 + LOAD_STATE_VOLUME_DOCKER_ARG=$([[ -z $LOAD_STATE_FILE ]] && echo "" || echo "-v $LOAD_STATE_FILE:/load-state.json") + DUMP_STATE_VOLUME_DOCKER_ARG=$([[ -z $DUMP_STATE_FILE ]] && echo "" || echo "-v $DUMP_STATE_FILE:/dump-state.json") + LOAD_STATE_ANVIL_ARG=$([[ -z $LOAD_STATE_FILE ]] && echo "" || echo "--load-state /load-state.json") + DUMP_STATE_ANVIL_ARG=$([[ -z $DUMP_STATE_FILE ]] && echo "" || echo "--dump-state /dump-state.json") + + echo $LOAD_STATE_VOLUME_DOCKER_ARG $DUMP_STATE_VOLUME_DOCKER_ARG + echo $LOAD_STATE_ANVIL_ARG $DUMP_STATE_ANVIL_ARG + trap 'docker stop anvil' EXIT + docker run --rm -d --name anvil -p 8545:8545 $LOAD_STATE_VOLUME_DOCKER_ARG $DUMP_STATE_VOLUME_DOCKER_ARG \ + --entrypoint anvil \ + $FOUNDRY_IMAGE \ + $LOAD_STATE_ANVIL_ARG $DUMP_STATE_ANVIL_ARG --host 0.0.0.0 + sleep 2 +} diff --git a/temp-incredible-squaring-avs/tests/integration/integration_test.go b/temp-incredible-squaring-avs/tests/integration/integration_test.go new file mode 100644 index 0000000..963cc17 --- /dev/null +++ b/temp-incredible-squaring-avs/tests/integration/integration_test.go @@ -0,0 +1,242 @@ +package integration_test + +import ( + "context" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "testing" + "time" + + "github.com/Layr-Labs/eigensdk-go/chainio/clients" + "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" + "github.com/Layr-Labs/eigensdk-go/chainio/clients/wallet" + "github.com/Layr-Labs/eigensdk-go/chainio/txmgr" + sdklogging "github.com/Layr-Labs/eigensdk-go/logging" + "github.com/Layr-Labs/eigensdk-go/signerv2" + sdkutils "github.com/Layr-Labs/eigensdk-go/utils" + "github.com/Layr-Labs/incredible-squaring-avs/aggregator" + "github.com/Layr-Labs/incredible-squaring-avs/core/chainio" + "github.com/Layr-Labs/incredible-squaring-avs/core/config" + "github.com/Layr-Labs/incredible-squaring-avs/operator" + "github.com/Layr-Labs/incredible-squaring-avs/types" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go/wait" +) + +type IntegrationClients struct { + Sdkclients clients.Clients +} + +func TestIntegration(t *testing.T) { + log.Println("This test takes ~50 seconds to run...") + + /* Start the anvil chain */ + anvilC := startAnvilTestContainer() + // Not sure why but deferring anvilC.Terminate() causes a panic when the test finishes... + // so letting it terminate silently for now + anvilEndpoint, err := anvilC.Endpoint(context.Background(), "") + if err != nil { + t.Error(err) + } + + /* Prepare the config file for aggregator */ + var aggConfigRaw config.ConfigRaw + aggConfigFilePath := "../../config-files/aggregator.yaml" + sdkutils.ReadYamlConfig(aggConfigFilePath, &aggConfigRaw) + aggConfigRaw.EthRpcUrl = "http://" + anvilEndpoint + aggConfigRaw.EthWsUrl = "ws://" + anvilEndpoint + + var credibleSquaringDeploymentRaw config.IncredibleSquaringDeploymentRaw + credibleSquaringDeploymentFilePath := "../../contracts/script/output/31337/credible_squaring_avs_deployment_output.json" + sdkutils.ReadJsonConfig(credibleSquaringDeploymentFilePath, &credibleSquaringDeploymentRaw) + + logger, err := sdklogging.NewZapLogger(aggConfigRaw.Environment) + if err != nil { + t.Fatalf("Failed to create logger: %s", err.Error()) + } + ethRpcClient, err := eth.NewClient(aggConfigRaw.EthRpcUrl) + if err != nil { + t.Fatalf("Failed to create eth client: %s", err.Error()) + } + ethWsClient, err := eth.NewClient(aggConfigRaw.EthWsUrl) + if err != nil { + t.Fatalf("Failed to create eth client: %s", err.Error()) + } + + aggregatorEcdsaPrivateKeyString := "0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6" + if aggregatorEcdsaPrivateKeyString[:2] == "0x" { + aggregatorEcdsaPrivateKeyString = aggregatorEcdsaPrivateKeyString[2:] + } + aggregatorEcdsaPrivateKey, err := crypto.HexToECDSA(aggregatorEcdsaPrivateKeyString) + if err != nil { + t.Fatalf("Cannot parse ecdsa private key: %s", err.Error()) + } + aggregatorAddr, err := sdkutils.EcdsaPrivateKeyToAddress(aggregatorEcdsaPrivateKey) + if err != nil { + t.Fatalf("Cannot get operator address: %s", err.Error()) + } + + chainId, err := ethRpcClient.ChainID(context.Background()) + if err != nil { + t.Fatalf("Cannot get chainId: %s", err.Error()) + } + + privateKeySigner, _, err := signerv2.SignerFromConfig(signerv2.Config{PrivateKey: aggregatorEcdsaPrivateKey}, chainId) + if err != nil { + t.Fatalf("Cannot create signer: %s", err.Error()) + } + skWallet, err := wallet.NewPrivateKeyWallet(ethRpcClient, privateKeySigner, aggregatorAddr, logger) + if err != nil { + panic(err) + } + txMgr := txmgr.NewSimpleTxManager(skWallet, ethRpcClient, logger, aggregatorAddr) + + config := &config.Config{ + EcdsaPrivateKey: aggregatorEcdsaPrivateKey, + Logger: logger, + EthHttpRpcUrl: aggConfigRaw.EthRpcUrl, + EthHttpClient: ethRpcClient, + EthWsRpcUrl: aggConfigRaw.EthWsUrl, + EthWsClient: ethWsClient, + OperatorStateRetrieverAddr: common.HexToAddress(credibleSquaringDeploymentRaw.Addresses.OperatorStateRetrieverAddr), + IncredibleSquaringRegistryCoordinatorAddr: common.HexToAddress(credibleSquaringDeploymentRaw.Addresses.RegistryCoordinatorAddr), + AggregatorServerIpPortAddr: aggConfigRaw.AggregatorServerIpPortAddr, + RegisterOperatorOnStartup: aggConfigRaw.RegisterOperatorOnStartup, + TxMgr: txMgr, + AggregatorAddress: aggregatorAddr, + } + + /* Prepare the config file for operator */ + nodeConfig := types.NodeConfig{} + nodeConfigFilePath := "../../config-files/operator.anvil.yaml" + err = sdkutils.ReadYamlConfig(nodeConfigFilePath, &nodeConfig) + if err != nil { + t.Fatalf("Failed to read yaml config: %s", err.Error()) + } + /* Register operator*/ + // log.Println("registering operator for integration tests") + // we need to do this dynamically and can't just hardcode a registered operator into the anvil + // state because the anvil state dump doesn't also dump the receipts tree so we lose events, + // and the aggregator thus can't get the operator's pubkey + // operatorRegistrationCmd := exec.Command("bash", "./operator-registration.sh") + // err = operatorRegistrationCmd.Run() + // if err != nil { + // t.Fatalf("Failed to register operator: %s", err.Error()) + // } + + ctx, cancel := context.WithTimeout(context.Background(), 65*time.Second) + defer cancel() + /* start operator */ + // the passwords are set to empty strings + log.Println("starting operator for integration tests") + os.Setenv("OPERATOR_BLS_KEY_PASSWORD", "") + os.Setenv("OPERATOR_ECDSA_KEY_PASSWORD", "") + nodeConfig.BlsPrivateKeyStorePath = "../keys/test.bls.key.json" + nodeConfig.EcdsaPrivateKeyStorePath = "../keys/test.ecdsa.key.json" + nodeConfig.RegisterOperatorOnStartup = true + nodeConfig.EthRpcUrl = "http://" + anvilEndpoint + nodeConfig.EthWsUrl = "ws://" + anvilEndpoint + operator, err := operator.NewOperatorFromConfig(nodeConfig) + if err != nil { + t.Fatalf("Failed to create operator: %s", err.Error()) + } + go operator.Start(ctx) + log.Println("Started operator. Sleeping 15 seconds to give it time to register...") + time.Sleep(15 * time.Second) + + /* start aggregator */ + log.Println("starting aggregator for integration tests") + agg, err := aggregator.NewAggregator(config) + if err != nil { + t.Fatalf("Failed to create aggregator: %s", err.Error()) + } + go agg.Start(ctx) + log.Println("Started aggregator. Sleeping 20 seconds to give operator time to answer task 1...") + time.Sleep(20 * time.Second) + + // get avsRegistry client to interact with the chain + avsReader, err := chainio.BuildAvsReaderFromConfig(config) + if err != nil { + t.Fatalf("Cannot create AVS Reader: %s", err.Error()) + } + + // check if the task is recorded in the contract for task index 1 + taskHash, err := avsReader.AvsServiceBindings.TaskManager.AllTaskHashes(&bind.CallOpts{}, 1) + if err != nil { + t.Fatalf("Cannot get task hash: %s", err.Error()) + } + if taskHash == [32]byte{} { + t.Fatalf("Task hash is empty") + } + + // check if the task response is recorded in the contract for task index 1 + taskResponseHash, err := avsReader.AvsServiceBindings.TaskManager.AllTaskResponses(&bind.CallOpts{}, 1) + log.Printf("taskResponseHash: %v", taskResponseHash) + if err != nil { + t.Fatalf("Cannot get task response hash: %s", err.Error()) + } + if taskResponseHash == [32]byte{} { + t.Fatalf("Task response hash is empty") + } + +} + +// TODO(samlaf): have to advance chain to a block where the task is answered +func startAnvilTestContainer() testcontainers.Container { + integrationDir, err := os.Getwd() + if err != nil { + panic(err) + } + + ctx := context.Background() + req := testcontainers.ContainerRequest{ + Image: "ghcr.io/foundry-rs/foundry:latest", + Mounts: testcontainers.ContainerMounts{ + testcontainers.ContainerMount{ + Source: testcontainers.GenericBindMountSource{ + HostPath: filepath.Join(integrationDir, "../anvil/avs-and-eigenlayer-deployed-anvil-state.json"), + }, + Target: "/root/.anvil/state.json", + }, + }, + Entrypoint: []string{"anvil"}, + Cmd: []string{"--host", "0.0.0.0", "--load-state", "/root/.anvil/state.json"}, + ExposedPorts: []string{"8545/tcp"}, + WaitingFor: wait.ForLog("Listening on"), + } + anvilC, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ + ContainerRequest: req, + Started: true, + }) + if err != nil { + panic(err) + } + // this is needed temporarily because anvil restarts at 0 block when we load a state... + // see comment in start-anvil-chain-with-el-and-avs-deployed.sh + advanceChain(anvilC) + return anvilC +} + +func advanceChain(anvilC testcontainers.Container) { + anvilEndpoint, err := anvilC.Endpoint(context.Background(), "") + if err != nil { + panic(err) + } + rpcUrl := "http://" + anvilEndpoint + cmd := exec.Command("bash", "-c", + fmt.Sprintf( + `cast rpc anvil_mine 100 --rpc-url %s`, + rpcUrl), + ) + cmd.Dir = "../../contracts" + err = cmd.Run() + if err != nil { + panic(err) + } +} diff --git a/temp-incredible-squaring-avs/tests/keys/test.bls.key.json b/temp-incredible-squaring-avs/tests/keys/test.bls.key.json new file mode 100644 index 0000000..72d5c64 --- /dev/null +++ b/temp-incredible-squaring-avs/tests/keys/test.bls.key.json @@ -0,0 +1 @@ +{"pubKey":"E([643552363890320897587044283125191574906281609959531590546948318138132520777,7028377728703212953187883551402495866059211864756496641401904395458852281995])","crypto":{"cipher":"aes-128-ctr","ciphertext":"8221f69293d98ca9d46c52a2747b61755c6bb71f41e951154af3bcbc0daef2b8","cipherparams":{"iv":"d8a38c68f3400aeb93084672b6e3ae61"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"c41150482e6acfc2f0fcfd68b67f28ef22de8aa3f982048bdaf793c2e3ac3730"},"mac":"879c2831169d9ac70c662ebca90b9f3cd63761d0924bdbbde0a82a306baf44cd"}} \ No newline at end of file diff --git a/temp-incredible-squaring-avs/tests/keys/test.ecdsa.key.json b/temp-incredible-squaring-avs/tests/keys/test.ecdsa.key.json new file mode 100644 index 0000000..7f3380d --- /dev/null +++ b/temp-incredible-squaring-avs/tests/keys/test.ecdsa.key.json @@ -0,0 +1 @@ +{"address":"860b6912c2d0337ef05bbc89b0c2cb6cbaeab4a5","crypto":{"cipher":"aes-128-ctr","ciphertext":"37ab29382354906d7b33b0ad1b00c539dfb69ea85997e470baba7601b0faa373","cipherparams":{"iv":"b7642683ba782688cc4da76dd5c61fce"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"fdc108d3e6388174f4cf6d5abe6de2364c96dcc03c4f1bddb1b47b01dce742e2"},"mac":"d4fff8d963a7815a7203f8c73b3047a2e5efcefb8163e6df316cc55f79df0cc2"},"id":"0c401f60-9d1f-4918-a823-1866984f8fcd","version":3} \ No newline at end of file diff --git a/temp-incredible-squaring-avs/tests/utils.go b/temp-incredible-squaring-avs/tests/utils.go new file mode 100644 index 0000000..2097c27 --- /dev/null +++ b/temp-incredible-squaring-avs/tests/utils.go @@ -0,0 +1,42 @@ +package tests + +import ( + "bytes" + "fmt" + "log" + "os/exec" + "time" +) + +// Make sure to stop the anvil subprocess by calling anvilCmd.Process.Kill() +func StartAnvilChainAndDeployContracts() *exec.Cmd { + fmt.Println("Starting anvil...") + anvilCmd := exec.Command("anvil", "--fork-url", "https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161") + err := anvilCmd.Start() + if err != nil { + log.Fatal(err.Error()) + } + + fmt.Println("Sleeping for 2 seconds to give time for anvil to start before we deploy contracts...") + time.Sleep(2 * time.Second) + + fmt.Println("Deploying contracts...") + cmd := exec.Command("forge", "script", "script/CredibleSquaringDeployer.s.sol", + "--rpc-url", "http://localhost:8545", + "--private-key", "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", + "--broadcast", + ) + cmd.Dir = "./contracts" + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + err = cmd.Run() + + if err != nil { + fmt.Println(stderr.String()) + log.Fatal(err.Error()) + } + fmt.Println(stdout.String()) + + return anvilCmd +} diff --git a/temp-incredible-squaring-avs/types/avs_config.go b/temp-incredible-squaring-avs/types/avs_config.go new file mode 100644 index 0000000..5157698 --- /dev/null +++ b/temp-incredible-squaring-avs/types/avs_config.go @@ -0,0 +1,20 @@ +package types + +type NodeConfig struct { + // used to set the logger level (true = info, false = debug) + Production bool `yaml:"production"` + OperatorAddress string `yaml:"operator_address"` + OperatorStateRetrieverAddress string `yaml:"operator_state_retriever_address"` + AVSRegistryCoordinatorAddress string `yaml:"avs_registry_coordinator_address"` + TokenStrategyAddr string `yaml:"token_strategy_addr"` + EthRpcUrl string `yaml:"eth_rpc_url"` + EthWsUrl string `yaml:"eth_ws_url"` + BlsPrivateKeyStorePath string `yaml:"bls_private_key_store_path"` + EcdsaPrivateKeyStorePath string `yaml:"ecdsa_private_key_store_path"` + AggregatorServerIpPortAddress string `yaml:"aggregator_server_ip_port_address"` + RegisterOperatorOnStartup bool `yaml:"register_operator_on_startup"` + EigenMetricsIpPortAddress string `yaml:"eigen_metrics_ip_port_address"` + EnableMetrics bool `yaml:"enable_metrics"` + NodeApiIpPortAddress string `yaml:"node_api_ip_port_address"` + EnableNodeApi bool `yaml:"enable_node_api"` +}