diff --git a/.changeset/bright-keys-whisper.md b/.changeset/bright-keys-whisper.md new file mode 100644 index 00000000000..16bf56b2ac9 --- /dev/null +++ b/.changeset/bright-keys-whisper.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +allow different decimals on different chains for token pools diff --git a/.changeset/kind-parents-jump.md b/.changeset/kind-parents-jump.md new file mode 100644 index 00000000000..e633f1af1fe --- /dev/null +++ b/.changeset/kind-parents-jump.md @@ -0,0 +1,11 @@ +--- +"chainlink": patch +--- + +Add two new metrics for monitoring LLO transmitter health #added + +`llo_mercurytransmitter_concurrent_transmit_gauge` +Gauge that measures the number of transmit threads currently waiting on a remote transmit call. You may wish to alert if this exceeds some number for a given period of time, or if it ever reaches its max. + +`llo_mercurytransmitter_concurrent_delete_gauge` +Gauge that measures the number of delete threads currently waiting on a delete call to the DB. You may wish to alert if this exceeds some number for a given period of time, or if it ever reaches its max. diff --git a/.changeset/late-seals-battle.md b/.changeset/late-seals-battle.md new file mode 100644 index 00000000000..194aa4f380e --- /dev/null +++ b/.changeset/late-seals-battle.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Update deployment address book to support non-evm chains diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 5155ba80b4b..bf3b49eef7b 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -1012,8 +1012,8 @@ runner-test-matrix: test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 E2E_JD_VERSION: 0.6.0 - E2E_RMN_RAGEPROXY_VERSION: master-5208d09 - E2E_RMN_AFN2PROXY_VERSION: master-5208d09 + E2E_RMN_RAGEPROXY_VERSION: master-f461a9e + E2E_RMN_AFN2PROXY_VERSION: master-f461a9e - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_MultipleMessagesOnOneLaneNoWaitForExec$ path: integration-tests/smoke/ccip/ccip_rmn_test.go @@ -1027,8 +1027,8 @@ runner-test-matrix: test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 E2E_JD_VERSION: 0.6.0 - E2E_RMN_RAGEPROXY_VERSION: master-5208d09 - E2E_RMN_AFN2PROXY_VERSION: master-5208d09 + E2E_RMN_RAGEPROXY_VERSION: master-f461a9e + E2E_RMN_AFN2PROXY_VERSION: master-f461a9e # Enable after flaking issue is resolved # - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_NotEnoughObservers$ @@ -1043,8 +1043,8 @@ runner-test-matrix: # test_env_vars: # E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 # E2E_JD_VERSION: 0.6.0 -# E2E_RMN_RAGEPROXY_VERSION: master-5208d09 -# E2E_RMN_AFN2PROXY_VERSION: master-5208d09 +# E2E_RMN_RAGEPROXY_VERSION: master-f461a9e +# E2E_RMN_AFN2PROXY_VERSION: master-f461a9e - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_DifferentSigners$ path: integration-tests/smoke/ccip/ccip_rmn_test.go @@ -1058,8 +1058,8 @@ runner-test-matrix: test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 E2E_JD_VERSION: 0.6.0 - E2E_RMN_RAGEPROXY_VERSION: master-5208d09 - E2E_RMN_AFN2PROXY_VERSION: master-5208d09 + E2E_RMN_RAGEPROXY_VERSION: master-f461a9e + E2E_RMN_AFN2PROXY_VERSION: master-f461a9e # Enable after flaking issue is resolved # - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_NotEnoughSigners$ @@ -1074,8 +1074,8 @@ runner-test-matrix: # test_env_vars: # E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 # E2E_JD_VERSION: 0.6.0 -# E2E_RMN_RAGEPROXY_VERSION: master-5208d09 -# E2E_RMN_AFN2PROXY_VERSION: master-5208d09 +# E2E_RMN_RAGEPROXY_VERSION: master-f461a9e +# E2E_RMN_AFN2PROXY_VERSION: master-f461a9e - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_DifferentRmnNodesForDifferentChains$ @@ -1090,8 +1090,8 @@ runner-test-matrix: test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 E2E_JD_VERSION: 0.6.0 - E2E_RMN_RAGEPROXY_VERSION: master-5208d09 - E2E_RMN_AFN2PROXY_VERSION: master-5208d09 + E2E_RMN_RAGEPROXY_VERSION: master-f461a9e + E2E_RMN_AFN2PROXY_VERSION: master-f461a9e # END: CCIPv1.6 tests @@ -1109,19 +1109,6 @@ runner-test-matrix: test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json test_env_vars: E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 - - - id: ccip-smoke-1.4-pools - path: integration-tests/ccip-tests/smoke/ccip_test.go - test_env_type: docker - runs_on: ubuntu-latest - triggers: - - PR E2E CCIP Tests - - Merge Queue E2E CCIP Tests - - Nightly E2E Tests - test_cmd: cd integration-tests/ccip-tests/smoke && go test ccip_test.go -test.run ^TestSmokeCCIPForBidirectionalLane$ -timeout 30m -count=1 -test.parallel=1 -json - test_env_vars: - E2E_TEST_SELECTED_NETWORK: SIMULATED_1,SIMULATED_2 - test_config_override_path: integration-tests/ccip-tests/testconfig/tomls/contract-version1.4.toml - id: ccip-smoke-usdc path: integration-tests/ccip-tests/smoke/ccip_test.go diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 5c931ed9870..c38ecd918ae 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -231,26 +231,14 @@ jobs: echo "COUNT=50" >> $GITHUB_ENV echo "FUZZ_TIMEOUT_MINUTES=10">> $GITHUB_ENV - - name: Install gotestloghelper - if: ${{ needs.filter.outputs.should-run-ci-core == 'true' }} - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/gotestloghelper@v1.50.0 - - name: Run tests if: ${{ needs.filter.outputs.should-run-ci-core == 'true' }} id: run-tests env: OUTPUT_FILE: ./output.txt - USE_TEE: false CL_DATABASE_URL: ${{ env.DB_URL }} run: ./tools/bin/${{ matrix.type.cmd }} ./... - - name: Print Filtered Test Results - if: ${{ failure() && needs.filter.outputs.should-run-ci-core == 'true' && steps.run-tests.conclusion == 'failure' }} - run: | - if [[ "${{ matrix.type.printResults }}" == "true" ]]; then - cat output.txt | gotestloghelper -ci - fi - - name: Print Races id: print-races if: ${{ failure() && matrix.type.cmd == 'go_core_race_tests' && needs.filter.outputs.should-run-ci-core == 'true' }} @@ -463,15 +451,15 @@ jobs: SONAR_SCANNER_OPTS: "-Xms6g -Xmx8g" trigger-flaky-test-detection-for-root-project: - name: Find New Flaky Tests In Chainlink Project - uses: ./.github/workflows/find-new-flaky-tests.yml + name: Flakeguard Root Project + uses: ./.github/workflows/flakeguard.yml if: ${{ github.event_name == 'pull_request' }} with: repoUrl: 'https://github.com/smartcontractkit/chainlink' projectPath: '.' baseRef: ${{ github.base_ref }} headRef: ${{ github.head_ref }} - runThreshold: '0.99' + maxPassRatio: '1.0' findByTestFilesDiff: true findByAffectedPackages: false slackNotificationAfterTestsChannelId: 'C07TRF65CNS' #flaky-test-detector-notifications @@ -480,8 +468,8 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} trigger-flaky-test-detection-for-deployment-project: - name: Find New Flaky Tests In Deployment Project - uses: ./.github/workflows/find-new-flaky-tests.yml + name: Flakeguard Deployment Project + uses: ./.github/workflows/flakeguard.yml needs: [filter] if: ${{ github.event_name == 'pull_request' && needs.filter.outputs.deployment-changes == 'true'}} with: @@ -489,7 +477,7 @@ jobs: projectPath: 'deployment' baseRef: ${{ github.base_ref }} headRef: ${{ github.head_ref }} - runThreshold: '0.99' + maxPassRatio: '1.0' findByTestFilesDiff: true findByAffectedPackages: false slackNotificationAfterTestsChannelId: 'C07TRF65CNS' #flaky-test-detector-notifications diff --git a/.github/workflows/run-find-new-flaky-tests.yml b/.github/workflows/flakeguard-on-demand.yml similarity index 74% rename from .github/workflows/run-find-new-flaky-tests.yml rename to .github/workflows/flakeguard-on-demand.yml index d1318719349..0ac8444a542 100644 --- a/.github/workflows/run-find-new-flaky-tests.yml +++ b/.github/workflows/flakeguard-on-demand.yml @@ -1,6 +1,9 @@ -name: Find Flaky Tests +name: Flakeguard On Demand on: + schedule: + # Run every night at 3:00 AM UTC + - cron: '0 3 * * *' workflow_dispatch: inputs: repoUrl: @@ -26,12 +29,12 @@ on: required: false type: boolean description: 'Run all tests in the project.' - default: false - runThreshold: + default: true + maxPassRatio: required: false type: string - description: 'The threshold for the number of times a test can fail before being considered flaky.' - default: '0.8' + description: 'The maximum (non-inclusive) pass ratio threshold for a test to be considered a failure. Any tests below this pass rate will be considered flaky.' + default: '1.0' findByTestFilesDiff: required: false type: boolean @@ -41,7 +44,7 @@ on: required: false type: boolean description: 'Find new or updated test packages by comparing affected packages.' - default: true + default: false slack_notification_after_tests_channel_id: description: "Slack channel ID to send the notification to for failed tests." required: false @@ -49,23 +52,24 @@ on: extraArgs: required: false type: string - default: '{}' - description: 'JSON of extra arguments for the workflow.' + default: '{ "skipped_tests": "TestChainComponents", "test_repeat_count": "5", "all_tests_runner": "ubuntu22.04-32cores-128GB", "all_tests_runner_count": "3", "min_pass_ratio": "0", "run_with_race": "false" }' + description: 'JSON of extra arguments for the workflow.' jobs: trigger-flaky-test-detection: name: Find Flaky Tests - uses: ./.github/workflows/find-new-flaky-tests.yml + uses: ./.github/workflows/flakeguard.yml with: repoUrl: ${{ inputs.repoUrl }} baseRef: ${{ inputs.baseRef }} projectPath: ${{ inputs.projectPath }} headRef: ${{ inputs.headRef }} - runThreshold: ${{ inputs.runThreshold }} + maxPassRatio: ${{ inputs.maxPassRatio }} runAllTests: ${{ inputs.runAllTests }} findByTestFilesDiff: ${{ inputs.findByTestFilesDiff }} findByAffectedPackages: ${{ inputs.findByAffectedPackages }} slackNotificationAfterTestsChannelId: ${{ inputs.slack_notification_after_tests_channel_id }} extraArgs: ${{ inputs.extraArgs }} secrets: - SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} \ No newline at end of file + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + \ No newline at end of file diff --git a/.github/workflows/find-new-flaky-tests.yml b/.github/workflows/flakeguard.yml similarity index 96% rename from .github/workflows/find-new-flaky-tests.yml rename to .github/workflows/flakeguard.yml index a685f4f5e70..8364a5c142a 100644 --- a/.github/workflows/find-new-flaky-tests.yml +++ b/.github/workflows/flakeguard.yml @@ -1,4 +1,4 @@ -name: Find Flaky Tests +name: Flakeguard on: workflow_call: @@ -25,11 +25,11 @@ on: type: boolean description: 'Run all tests in the project.' default: false - runThreshold: + maxPassRatio: required: false type: string - description: 'The threshold for the number of times a test can fail before being considered flaky.' - default: '0.9' + description: 'The maximum (non-inclusive) pass ratio threshold for a test to be considered a failure. Any tests below this pass rate will be considered flaky.' + default: '1.0' findByTestFilesDiff: required: false type: boolean @@ -64,7 +64,6 @@ env: DEFAULT_RUNNER: 'ubuntu-latest' # The default runner to use for running tests. UPLOAD_ALL_TEST_RESULTS: ${{ fromJson(inputs.extraArgs)['upload_all_test_results'] || 'false' }} # Whether to upload all test results as artifacts. PRINT_FAILED_TESTS: ${{ fromJson(inputs.extraArgs)['print_failed_tests'] || 'false' }} # Whether to print failed tests in the GitHub console. - MIN_PASS_RATIO: ${{ fromJson(inputs.extraArgs)['min_pass_ratio'] || '0.001' }} # The minimum pass ratio for a test to be considered as flaky. Used to distinguish between tests that are truly flaky (with inconsistent results) and those that are consistently failing. Set to 0 if you want to consider all failed tests as flaky. jobs: get-tests: @@ -99,7 +98,7 @@ jobs: - name: Install flakeguard shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@8b02ed1703ef40755a4c46ff454cf4ff2e89275d + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@be06798af83ef6d9f7cf04e8b10a8484520c5061 # flakguard@0.0.1 - name: Find new or updated test packages if: ${{ inputs.runAllTests == false }} @@ -258,11 +257,11 @@ jobs: - name: Install flakeguard shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@8b02ed1703ef40755a4c46ff454cf4ff2e89275d + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@be06798af83ef6d9f7cf04e8b10a8484520c5061 # flakguard@0.0.1 - name: Run tests with flakeguard shell: bash - run: flakeguard run --project-path=${{ inputs.projectPath }} --test-packages=${{ matrix.testPackages }} --run-count=${{ env.TEST_REPEAT_COUNT }} --min-pass-ratio=${{ env.MIN_PASS_RATIO }} --threshold=${{ inputs.runThreshold }} --race=${{ env.RUN_WITH_RACE }} --skip-tests=${{ env.SKIPPED_TESTS }} --print-failed-tests=${{ env.PRINT_FAILED_TESTS }} --output-json=test-result.json + run: flakeguard run --project-path=${{ inputs.projectPath }} --test-packages=${{ matrix.testPackages }} --run-count=${{ env.TEST_REPEAT_COUNT }} --max-pass-ratio=${{ inputs.maxPassRatio }} --race=${{ env.RUN_WITH_RACE }} --skip-tests=${{ env.SKIPPED_TESTS }} --print-failed-tests=${{ env.PRINT_FAILED_TESTS }} --output-json=test-result.json env: CL_DATABASE_URL: ${{ env.DB_URL }} @@ -300,7 +299,7 @@ jobs: - name: Install flakeguard shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@8b02ed1703ef40755a4c46ff454cf4ff2e89275d + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@be06798af83ef6d9f7cf04e8b10a8484520c5061 # flakguard@0.0.1 - name: Set combined test results id: set_test_results diff --git a/.github/workflows/run-nightly-flaky-test-detector.yml b/.github/workflows/run-nightly-flaky-test-detector.yml deleted file mode 100644 index 1c5dc72d4a3..00000000000 --- a/.github/workflows/run-nightly-flaky-test-detector.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Run Nightly Flaky Test Detector - -on: - schedule: - # Run every night at 3:00 AM UTC - - cron: '0 3 * * *' - workflow_dispatch: # Allows manual trigger for debugging - -jobs: - trigger-flaky-test-detection: - name: Find Flaky Tests - uses: ./.github/workflows/find-new-flaky-tests.yml - with: - repoUrl: 'https://github.com/smartcontractkit/chainlink' - baseRef: 'origin/develop' - projectPath: '.' - runThreshold: '1' - runAllTests: true - extraArgs: '{ "skipped_tests": "TestChainComponents", "test_repeat_count": "5", "all_tests_runner": "ubuntu22.04-32cores-128GB", "all_tests_runner_count": "3", "min_pass_ratio": "0", "run_with_race": "false" }' - secrets: - SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} - \ No newline at end of file diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml index 222b3daa0ca..b94c0236155 100644 --- a/.github/workflows/solidity-foundry.yml +++ b/.github/workflows/solidity-foundry.yml @@ -34,13 +34,13 @@ jobs: { "name": "functions", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "keystone", "setup": { "run-coverage": true, "min-coverage": 72.8, "run-gas-snapshot": false, "run-forge-fmt": false }}, { "name": "l2ep", "setup": { "run-coverage": true, "min-coverage": 61.0, "run-gas-snapshot": true, "run-forge-fmt": false }}, - { "name": "liquiditymanager", "setup": { "run-coverage": true, "min-coverage": 46.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, + { "name": "liquiditymanager", "setup": { "run-coverage": true, "min-coverage": 44, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "llo-feeds", "setup": { "run-coverage": true, "min-coverage": 49.3, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "operatorforwarder", "setup": { "run-coverage": true, "min-coverage": 55.7, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "shared", "setup": { "run-coverage": true, "extra-coverage-params": "--no-match-path='*CallWithExactGas*' --ir-minimum", "min-coverage": 32.6, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "transmission", "setup": { "run-coverage": true, "min-coverage": 61.5, "run-gas-snapshot": true, "run-forge-fmt": false }}, { "name": "vrf", "setup": { "run-coverage": false, "min-coverage": 98.5, "run-gas-snapshot": false, "run-forge-fmt": false }}, - { "name": "workflow", "setup": { "run-coverage": true, "extra-coverage-params": "--ir-minimum", "min-coverage": 65.0, "run-gas-snapshot": false, "run-forge-fmt": true }} + { "name": "workflow", "setup": { "run-coverage": true, "extra-coverage-params": "--ir-minimum", "min-coverage": 96.0, "run-gas-snapshot": true, "run-forge-fmt": true }} ] EOF diff --git a/contracts/.changeset/modern-mayflies-give.md b/contracts/.changeset/modern-mayflies-give.md new file mode 100644 index 00000000000..c54f69e8489 --- /dev/null +++ b/contracts/.changeset/modern-mayflies-give.md @@ -0,0 +1,10 @@ +--- +'@chainlink/contracts': patch +--- + +allow multiple remote pools per chain selector + + +PR issue: CCIP-4269 + +Solidity Review issue: CCIP-3966 \ No newline at end of file diff --git a/contracts/.changeset/ninety-lions-complain.md b/contracts/.changeset/ninety-lions-complain.md new file mode 100644 index 00000000000..32c81e46eee --- /dev/null +++ b/contracts/.changeset/ninety-lions-complain.md @@ -0,0 +1,5 @@ +--- +'@chainlink/contracts': patch +--- + +Update token pool factory to support new token pool design with arbitrary decimals #bugfix diff --git a/contracts/GNUmakefile b/contracts/GNUmakefile index a12e7d2075c..4066c76037e 100644 --- a/contracts/GNUmakefile +++ b/contracts/GNUmakefile @@ -43,7 +43,7 @@ mockery: $(mockery) ## Install mockery. .PHONY: foundry foundry: ## Install foundry. - foundryup --version nightly-3ff3d0562215bca620e07c5c4c154eec8da0f04b + foundryup --version nightly-fb5f0e1c4d9b9b0861be3e3bd07963524c5ac08e .PHONY: foundry-refresh foundry-refresh: foundry diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index cd54b3e9bd7..487265ef580 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -4,23 +4,23 @@ ARMProxy_isCursed:test_call_ARMCallEmptyContract_Revert() (gas: 19412) ARMProxy_isCursed:test_isCursed_RevertReasonForwarded_Revert() (gas: 45210) ARMProxy_setARM:test_SetARM() (gas: 16599) ARMProxy_setARM:test_SetARMzero() (gas: 11275) -BurnFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28962) -BurnFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55385) -BurnFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 244305) -BurnFromMintTokenPool_lockOrBurn:test_setup_Success() (gas: 24231) -BurnMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 27681) -BurnMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55385) -BurnMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 242205) -BurnMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 17873) -BurnMintTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 28903) -BurnMintTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56399) -BurnMintTokenPool_releaseOrMint:test_PoolMint_Success() (gas: 112631) -BurnMintWithLockReleaseFlagTokenPool_lockOrBurn:test_LockOrBurn_CorrectReturnData_Success() (gas: 242835) -BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 28962) -BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 55385) -BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 244349) -BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 24255) -CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2076959) +BurnFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 27357) +BurnFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 54878) +BurnFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 244461) +BurnFromMintTokenPool_lockOrBurn:test_setup_Success() (gas: 24210) +BurnMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 27497) +BurnMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 54878) +BurnMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 242361) +BurnMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 17852) +BurnMintTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 27298) +BurnMintTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 54624) +BurnMintTokenPool_releaseOrMint:test_PoolMint_Success() (gas: 109448) +BurnMintWithLockReleaseFlagTokenPool_lockOrBurn:test_LockOrBurn_CorrectReturnData_Success() (gas: 242814) +BurnWithFromMintTokenPool_lockOrBurn:test_ChainNotAllowed_Revert() (gas: 27357) +BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 54878) +BurnWithFromMintTokenPool_lockOrBurn:test_PoolBurn_Success() (gas: 244505) +BurnWithFromMintTokenPool_lockOrBurn:test_Setup_Success() (gas: 24223) +CCIPClientExample_sanity:test_ImmutableExamples_Success() (gas: 2077713) CCIPHome__validateConfig:test__validateConfigLessTransmittersThanSigners_Success() (gas: 332619) CCIPHome__validateConfig:test__validateConfigSmallerFChain_Success() (gas: 458568) CCIPHome__validateConfig:test__validateConfig_ABIEncodedAddress_OfframpAddressCannotBeZero_Reverts() (gas: 289191) @@ -68,7 +68,7 @@ CCIPHome_setCandidate:test_setCandidate_success() (gas: 1365439) CCIPHome_supportsInterface:test_supportsInterface_success() (gas: 9885) DefensiveExampleTest:test_HappyPath_Success() (gas: 200540) DefensiveExampleTest:test_Recovery() (gas: 425013) -E2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1520337) +E2E:test_E2E_3MessagesMMultiOffRampSuccess_gas() (gas: 1512521) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_fallbackToWethTransfer() (gas: 96980) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_happyPath() (gas: 49812) EtherSenderReceiverTest_ccipReceive:test_ccipReceive_wrongToken() (gas: 17479) @@ -199,15 +199,15 @@ FeeQuoter_parseEVMExtraArgsFromBytes:test_EVMExtraArgsInvalidExtraArgsTag_Revert FeeQuoter_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV1_Success() (gas: 18534) FeeQuoter_parseEVMExtraArgsFromBytes:test_EVMExtraArgsV2_Success() (gas: 18657) FeeQuoter_processMessageArgs:test_applyTokensTransferFeeConfigUpdates_InvalidFeeRange_Revert() (gas: 21454) -FeeQuoter_processMessageArgs:test_processMessageArgs_InvalidEVMAddressDestToken_Revert() (gas: 44795) +FeeQuoter_processMessageArgs:test_processMessageArgs_InvalidEVMAddressDestToken_Revert() (gas: 44930) FeeQuoter_processMessageArgs:test_processMessageArgs_InvalidExtraArgs_Revert() (gas: 19986) FeeQuoter_processMessageArgs:test_processMessageArgs_MalformedEVMExtraArgs_Revert() (gas: 20383) FeeQuoter_processMessageArgs:test_processMessageArgs_MessageFeeTooHigh_Revert() (gas: 17954) -FeeQuoter_processMessageArgs:test_processMessageArgs_SourceTokenDataTooLarge_Revert() (gas: 123115) -FeeQuoter_processMessageArgs:test_processMessageArgs_TokenAmountArraysMismatching_Revert() (gas: 42124) +FeeQuoter_processMessageArgs:test_processMessageArgs_SourceTokenDataTooLarge_Revert() (gas: 123251) +FeeQuoter_processMessageArgs:test_processMessageArgs_TokenAmountArraysMismatching_Revert() (gas: 42192) FeeQuoter_processMessageArgs:test_processMessageArgs_WitEVMExtraArgsV2_Success() (gas: 28658) FeeQuoter_processMessageArgs:test_processMessageArgs_WithConvertedTokenAmount_Success() (gas: 29999) -FeeQuoter_processMessageArgs:test_processMessageArgs_WithCorrectPoolReturnData_Success() (gas: 76173) +FeeQuoter_processMessageArgs:test_processMessageArgs_WithCorrectPoolReturnData_Success() (gas: 76449) FeeQuoter_processMessageArgs:test_processMessageArgs_WithEVMExtraArgsV1_Success() (gas: 28256) FeeQuoter_processMessageArgs:test_processMessageArgs_WithEmptyEVMExtraArgs_Success() (gas: 26115) FeeQuoter_processMessageArgs:test_processMessageArgs_WithLinkTokenAmount_Success() (gas: 19573) @@ -227,31 +227,31 @@ FeeQuoter_validateDestFamilyAddress:test_InvalidEVMAddressPrecompiles_Revert() ( FeeQuoter_validateDestFamilyAddress:test_InvalidEVMAddress_Revert() (gas: 10884) FeeQuoter_validateDestFamilyAddress:test_ValidEVMAddress_Success() (gas: 6819) FeeQuoter_validateDestFamilyAddress:test_ValidNonEVMAddress_Success() (gas: 6545) -HybridLockReleaseUSDCTokenPool_TransferLiquidity:test_cannotTransferLiquidityDuringPendingMigration_Revert() (gas: 176981) -HybridLockReleaseUSDCTokenPool_TransferLiquidity:test_transferLiquidity_Success() (gas: 167025) -HybridLockReleaseUSDCTokenPool_lockOrBurn:test_PrimaryMechanism_Success() (gas: 135960) -HybridLockReleaseUSDCTokenPool_lockOrBurn:test_WhileMigrationPause_Revert() (gas: 109713) -HybridLockReleaseUSDCTokenPool_lockOrBurn:test_onLockReleaseMechanism_Success() (gas: 147008) -HybridLockReleaseUSDCTokenPool_lockOrBurn:test_onLockReleaseMechanism_thenswitchToPrimary_Success() (gas: 209322) -HybridLockReleaseUSDCTokenPool_releaseOrMint:test_OnLockReleaseMechanism_Success() (gas: 216938) -HybridLockReleaseUSDCTokenPool_releaseOrMint:test_WhileMigrationPause_Revert() (gas: 113472) -HybridLockReleaseUSDCTokenPool_releaseOrMint:test_incomingMessageWithPrimaryMechanism() (gas: 269112) -LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 2788658) -LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 30088) -LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Success() (gas: 80282) -LockReleaseTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 59734) -LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 2785053) -LockReleaseTokenPool_provideLiquidity:test_Unauthorized_Revert() (gas: 11489) -LockReleaseTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 72956) -LockReleaseTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 56520) -LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 225800) -LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Revert() (gas: 10981) -LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Success() (gas: 18160) +HybridLockReleaseUSDCTokenPool_TransferLiquidity:test_cannotTransferLiquidityDuringPendingMigration_Revert() (gas: 176837) +HybridLockReleaseUSDCTokenPool_TransferLiquidity:test_transferLiquidity_Success() (gas: 166986) +HybridLockReleaseUSDCTokenPool_lockOrBurn:test_PrimaryMechanism_Success() (gas: 135860) +HybridLockReleaseUSDCTokenPool_lockOrBurn:test_WhileMigrationPause_Revert() (gas: 109696) +HybridLockReleaseUSDCTokenPool_lockOrBurn:test_onLockReleaseMechanism_Success() (gas: 146915) +HybridLockReleaseUSDCTokenPool_lockOrBurn:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209124) +HybridLockReleaseUSDCTokenPool_releaseOrMint:test_OnLockReleaseMechanism_Success() (gas: 213127) +HybridLockReleaseUSDCTokenPool_releaseOrMint:test_WhileMigrationPause_Revert() (gas: 109646) +HybridLockReleaseUSDCTokenPool_releaseOrMint:test_incomingMessageWithPrimaryMechanism() (gas: 265910) +LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquidity_Success() (gas: 3053405) +LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29734) +LockReleaseTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Success() (gas: 80647) +LockReleaseTokenPool_lockOrBurn:test_PoolBurnRevertNotHealthy_Revert() (gas: 59227) +LockReleaseTokenPool_provideLiquidity:test_LiquidityNotAccepted_Revert() (gas: 3049734) +LockReleaseTokenPool_provideLiquidity:test_Unauthorized_Revert() (gas: 11511) +LockReleaseTokenPool_releaseOrMint:test_ChainNotAllowed_Revert() (gas: 74108) +LockReleaseTokenPool_releaseOrMint:test_PoolMintNotHealthy_Revert() (gas: 54745) +LockReleaseTokenPool_releaseOrMint:test_ReleaseOrMint_Success() (gas: 223273) +LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Revert() (gas: 10936) +LockReleaseTokenPool_setRebalancer:test_SetRebalancer_Success() (gas: 18115) LockReleaseTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 10250) -LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_Success() (gas: 83306) -LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_transferTooMuch_Revert() (gas: 56079) +LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_Success() (gas: 83283) +LockReleaseTokenPool_transferLiquidity:test_transferLiquidity_transferTooMuch_Revert() (gas: 56056) LockReleaseTokenPool_withdrawalLiquidity:test_InsufficientLiquidity_Revert() (gas: 60188) -LockReleaseTokenPool_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11486) +LockReleaseTokenPool_withdrawalLiquidity:test_Unauthorized_Revert() (gas: 11464) MerkleMultiProofTest:test_CVE_2023_34459() (gas: 5456) MerkleMultiProofTest:test_EmptyLeaf_Revert() (gas: 3563) MerkleMultiProofTest:test_MerkleRoot256() (gas: 394891) @@ -352,12 +352,12 @@ NonceManager_NonceIncrementation:test_getIncrementedOutboundNonce_Success() (gas NonceManager_NonceIncrementation:test_incrementInboundNonce_Skip() (gas: 23706) NonceManager_NonceIncrementation:test_incrementInboundNonce_Success() (gas: 38778) NonceManager_NonceIncrementation:test_incrementNoncesInboundAndOutbound_Success() (gas: 71901) -NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 185739) -NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 189192) -NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 252176) -NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 220541) +NonceManager_OffRampUpgrade:test_NoPrevOffRampForChain_Success() (gas: 185776) +NonceManager_OffRampUpgrade:test_UpgradedNonceNewSenderStartsAtZero_Success() (gas: 189229) +NonceManager_OffRampUpgrade:test_UpgradedNonceStartsAtV1Nonce_Success() (gas: 252250) +NonceManager_OffRampUpgrade:test_UpgradedOffRampNonceSkipsIfMsgInFlight_Success() (gas: 220615) NonceManager_OffRampUpgrade:test_UpgradedSenderNoncesReadsPreviousRamp_Success() (gas: 60497) -NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 152904) +NonceManager_OffRampUpgrade:test_Upgraded_Success() (gas: 152941) NonceManager_OnRampUpgrade:test_UpgradeNonceNewSenderStartsAtZero_Success() (gas: 166101) NonceManager_OnRampUpgrade:test_UpgradeNonceStartsAtV1Nonce_Success() (gas: 195828) NonceManager_OnRampUpgrade:test_UpgradeSenderNoncesReadsPreviousRamp_Success() (gas: 139098) @@ -381,13 +381,13 @@ OffRamp_applySourceChainConfigUpdates:test_RouterAddress_Revert() (gas: 13441) OffRamp_applySourceChainConfigUpdates:test_ZeroOnRampAddress_Revert() (gas: 72724) OffRamp_applySourceChainConfigUpdates:test_ZeroSourceChainSelector_Revert() (gas: 15519) OffRamp_applySourceChainConfigUpdates:test_allowNonOnRampUpdateAfterLaneIsUsed_success() (gas: 285041) -OffRamp_batchExecute:test_MultipleReportsDifferentChainsSkipCursedChain_Success() (gas: 177349) -OffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 333175) -OffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 276441) -OffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 168334) -OffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187853) -OffRamp_batchExecute:test_SingleReport_Success() (gas: 156369) -OffRamp_batchExecute:test_Unhealthy_Success() (gas: 553667) +OffRamp_batchExecute:test_MultipleReportsDifferentChainsSkipCursedChain_Success() (gas: 177470) +OffRamp_batchExecute:test_MultipleReportsDifferentChains_Success() (gas: 333296) +OffRamp_batchExecute:test_MultipleReportsSameChain_Success() (gas: 276562) +OffRamp_batchExecute:test_MultipleReportsSkipDuplicate_Success() (gas: 168408) +OffRamp_batchExecute:test_OutOfBoundsGasLimitsAccess_Revert() (gas: 187974) +OffRamp_batchExecute:test_SingleReport_Success() (gas: 156406) +OffRamp_batchExecute:test_Unhealthy_Success() (gas: 545125) OffRamp_batchExecute:test_ZeroReports_Revert() (gas: 10600) OffRamp_commit:test_CommitOnRampMismatch_Revert() (gas: 92744) OffRamp_commit:test_FailedRMNVerification_Reverts() (gas: 63432) @@ -418,94 +418,94 @@ OffRamp_constructor:test_ZeroOnRampAddress_Revert() (gas: 162055) OffRamp_constructor:test_ZeroRMNRemote_Revert() (gas: 101378) OffRamp_constructor:test_ZeroTokenAdminRegistry_Revert() (gas: 101382) OffRamp_execute:test_IncorrectArrayType_Revert() (gas: 17639) -OffRamp_execute:test_LargeBatch_Success() (gas: 3374933) -OffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 371025) -OffRamp_execute:test_MultipleReports_Success() (gas: 298564) -OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 7049279) -OffRamp_execute:test_NoConfig_Revert() (gas: 6273749) -OffRamp_execute:test_NonArray_Revert() (gas: 27643) -OffRamp_execute:test_SingleReport_Success() (gas: 175627) -OffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147783) +OffRamp_execute:test_LargeBatch_Success() (gas: 3376243) +OffRamp_execute:test_MultipleReportsWithPartialValidationFailures_Success() (gas: 371146) +OffRamp_execute:test_MultipleReports_Success() (gas: 298685) +OffRamp_execute:test_NoConfigWithOtherConfigPresent_Revert() (gas: 7049316) +OffRamp_execute:test_NoConfig_Revert() (gas: 6273786) +OffRamp_execute:test_NonArray_Revert() (gas: 27680) +OffRamp_execute:test_SingleReport_Success() (gas: 175664) +OffRamp_execute:test_UnauthorizedTransmitter_Revert() (gas: 147820) OffRamp_execute:test_WrongConfigWithSigners_Revert() (gas: 6940958) OffRamp_execute:test_ZeroReports_Revert() (gas: 17361) OffRamp_executeSingleMessage:test_MessageSender_Revert() (gas: 18533) -OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 244285) +OffRamp_executeSingleMessage:test_NonContractWithTokens_Success() (gas: 237918) OffRamp_executeSingleMessage:test_NonContract_Success() (gas: 20363) -OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 205686) +OffRamp_executeSingleMessage:test_TokenHandlingError_Revert() (gas: 198836) OffRamp_executeSingleMessage:test_ZeroGasDONExecution_Revert() (gas: 48880) OffRamp_executeSingleMessage:test_executeSingleMessage_NoTokens_Success() (gas: 56102) OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidationNoRouterCall_Revert() (gas: 212824) OffRamp_executeSingleMessage:test_executeSingleMessage_WithFailingValidation_Revert() (gas: 85495) -OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 274393) +OffRamp_executeSingleMessage:test_executeSingleMessage_WithTokens_Success() (gas: 268026) OffRamp_executeSingleMessage:test_executeSingleMessage_WithVInterception_Success() (gas: 91918) -OffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 28666) -OffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 15584) -OffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 481623) -OffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 48303) -OffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 34108) -OffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 28831) -OffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 187607) -OffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 197746) -OffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 40694) -OffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 404953) -OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 248622) -OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 192288) -OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 212314) -OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 243661) -OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 141439) -OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 408827) -OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 58249) -OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 73816) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 582798) -OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 531349) -OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 26755) -OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 549373) -OffRamp_executeSingleReport:test_Unhealthy_Success() (gas: 549320) -OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 460462) -OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 135167) -OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 164806) +OffRamp_executeSingleReport:test_DisabledSourceChain_Revert() (gas: 28703) +OffRamp_executeSingleReport:test_EmptyReport_Revert() (gas: 15574) +OffRamp_executeSingleReport:test_InvalidSourcePoolAddress_Success() (gas: 471595) +OffRamp_executeSingleReport:test_ManualExecutionNotYetEnabled_Revert() (gas: 48340) +OffRamp_executeSingleReport:test_MismatchingDestChainSelector_Revert() (gas: 34145) +OffRamp_executeSingleReport:test_NonExistingSourceChain_Revert() (gas: 28868) +OffRamp_executeSingleReport:test_ReceiverError_Success() (gas: 187644) +OffRamp_executeSingleReport:test_RetryFailedMessageWithoutManualExecution_Revert() (gas: 197820) +OffRamp_executeSingleReport:test_RootNotCommitted_Revert() (gas: 40731) +OffRamp_executeSingleReport:test_RouterYULCall_Revert() (gas: 404990) +OffRamp_executeSingleReport:test_SingleMessageNoTokensOtherChain_Success() (gas: 248696) +OffRamp_executeSingleReport:test_SingleMessageNoTokensUnordered_Success() (gas: 192362) +OffRamp_executeSingleReport:test_SingleMessageNoTokens_Success() (gas: 212388) +OffRamp_executeSingleReport:test_SingleMessageToNonCCIPReceiver_Success() (gas: 243698) +OffRamp_executeSingleReport:test_SingleMessagesNoTokensSuccess_gas() (gas: 141476) +OffRamp_executeSingleReport:test_SkippedIncorrectNonceStillExecutes_Success() (gas: 402556) +OffRamp_executeSingleReport:test_SkippedIncorrectNonce_Success() (gas: 58286) +OffRamp_executeSingleReport:test_TokenDataMismatch_Revert() (gas: 73856) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensAndGE_Success() (gas: 574160) +OffRamp_executeSingleReport:test_TwoMessagesWithTokensSuccess_gas() (gas: 522711) +OffRamp_executeSingleReport:test_UnexpectedTokenData_Revert() (gas: 26839) +OffRamp_executeSingleReport:test_UnhealthySingleChainCurse_Revert() (gas: 540831) +OffRamp_executeSingleReport:test_Unhealthy_Success() (gas: 540778) +OffRamp_executeSingleReport:test_WithCurseOnAnotherSourceChain_Success() (gas: 451824) +OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessageUnordered_Success() (gas: 135241) +OffRamp_executeSingleReport:test__execute_SkippedAlreadyExecutedMessage_Success() (gas: 164880) OffRamp_getExecutionState:test_FillExecutionState_Success() (gas: 3888846) OffRamp_getExecutionState:test_GetDifferentChainExecutionState_Success() (gas: 121048) OffRamp_getExecutionState:test_GetExecutionState_Success() (gas: 89561) -OffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 81178) -OffRamp_manuallyExecute:test_manuallyExecute_DestinationGasAmountCountMismatch_Revert() (gas: 74108) -OffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 172480) -OffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 212935) -OffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 27166) -OffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 164939) -OffRamp_manuallyExecute:test_manuallyExecute_InvalidReceiverExecutionGasLimit_Revert() (gas: 27703) -OffRamp_manuallyExecute:test_manuallyExecute_InvalidTokenGasOverride_Revert() (gas: 55274) -OffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 489352) -OffRamp_manuallyExecute:test_manuallyExecute_MultipleReportsWithSingleCursedLane_Revert() (gas: 314370) -OffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2227767) -OffRamp_manuallyExecute:test_manuallyExecute_SourceChainSelectorMismatch_Revert() (gas: 165133) -OffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 225844) -OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 226384) -OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 773426) -OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 344159) +OffRamp_manuallyExecute:test_ManualExecGasLimitMismatchSingleReport_Revert() (gas: 81514) +OffRamp_manuallyExecute:test_manuallyExecute_DestinationGasAmountCountMismatch_Revert() (gas: 74194) +OffRamp_manuallyExecute:test_manuallyExecute_DoesNotRevertIfUntouched_Success() (gas: 172517) +OffRamp_manuallyExecute:test_manuallyExecute_FailedTx_Revert() (gas: 213009) +OffRamp_manuallyExecute:test_manuallyExecute_ForkedChain_Revert() (gas: 27203) +OffRamp_manuallyExecute:test_manuallyExecute_GasLimitMismatchMultipleReports_Revert() (gas: 165665) +OffRamp_manuallyExecute:test_manuallyExecute_InvalidReceiverExecutionGasLimit_Revert() (gas: 27740) +OffRamp_manuallyExecute:test_manuallyExecute_InvalidTokenGasOverride_Revert() (gas: 55317) +OffRamp_manuallyExecute:test_manuallyExecute_LowGasLimit_Success() (gas: 489426) +OffRamp_manuallyExecute:test_manuallyExecute_MultipleReportsWithSingleCursedLane_Revert() (gas: 314585) +OffRamp_manuallyExecute:test_manuallyExecute_ReentrancyFails_Success() (gas: 2224654) +OffRamp_manuallyExecute:test_manuallyExecute_SourceChainSelectorMismatch_Revert() (gas: 165207) +OffRamp_manuallyExecute:test_manuallyExecute_Success() (gas: 225918) +OffRamp_manuallyExecute:test_manuallyExecute_WithGasOverride_Success() (gas: 226458) +OffRamp_manuallyExecute:test_manuallyExecute_WithMultiReportGasOverride_Success() (gas: 773856) +OffRamp_manuallyExecute:test_manuallyExecute_WithPartialMessages_Success() (gas: 344327) OffRamp_releaseOrMintSingleToken:test__releaseOrMintSingleToken_NotACompatiblePool_Revert() (gas: 37654) -OffRamp_releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 104686) -OffRamp_releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 83114) +OffRamp_releaseOrMintSingleToken:test__releaseOrMintSingleToken_Success() (gas: 101487) +OffRamp_releaseOrMintSingleToken:test__releaseOrMintSingleToken_TokenHandlingError_transfer_Revert() (gas: 79931) OffRamp_releaseOrMintSingleToken:test_releaseOrMintToken_InvalidDataLength_Revert() (gas: 36812) -OffRamp_releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 94643) +OffRamp_releaseOrMintSingleToken:test_releaseOrMintToken_ReleaseOrMintBalanceMismatch_Revert() (gas: 91450) OffRamp_releaseOrMintSingleToken:test_releaseOrMintToken_TokenHandlingError_BalanceOf_Revert() (gas: 37323) -OffRamp_releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 86755) -OffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 162972) +OffRamp_releaseOrMintSingleToken:test_releaseOrMintToken_skip_ReleaseOrMintBalanceMismatch_if_pool_Revert() (gas: 83562) +OffRamp_releaseOrMintTokens:test_TokenHandlingError_Reverts() (gas: 156122) OffRamp_releaseOrMintTokens:test__releaseOrMintTokens_PoolIsNotAPool_Reverts() (gas: 23836) OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_InvalidDataLengthReturnData_Revert() (gas: 62866) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 80036) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 175147) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_WithGasOverride_Success() (gas: 177059) -OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 188281) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_PoolDoesNotSupportDest_Reverts() (gas: 78418) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_Success() (gas: 168774) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_WithGasOverride_Success() (gas: 170686) +OffRamp_releaseOrMintTokens:test_releaseOrMintTokens_destDenominatedDecimals_Success() (gas: 181914) OffRamp_setDynamicConfig:test_FeeQuoterZeroAddress_Revert() (gas: 11509) OffRamp_setDynamicConfig:test_NonOwner_Revert() (gas: 14019) OffRamp_setDynamicConfig:test_SetDynamicConfigWithInterceptor_Success() (gas: 47579) OffRamp_setDynamicConfig:test_SetDynamicConfig_Success() (gas: 25552) -OffRamp_trialExecute:test_RateLimitError_Success() (gas: 219967) -OffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 228644) -OffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 295716) -OffRamp_trialExecute:test_trialExecute_Success() (gas: 278190) -OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 251641) +OffRamp_trialExecute:test_RateLimitError_Success() (gas: 213117) +OffRamp_trialExecute:test_TokenHandlingErrorIsCaught_Success() (gas: 221794) +OffRamp_trialExecute:test_TokenPoolIsNotAContract_Success() (gas: 289349) +OffRamp_trialExecute:test_trialExecute_Success() (gas: 271823) +OnRampTokenPoolReentrancy:test_OnRampTokenPoolReentrancy_Success() (gas: 251706) OnRamp_applyAllowlistUpdates:test_applyAllowlistUpdates_InvalidAllowListRequestDisabledAllowListWithAdds() (gas: 17227) OnRamp_applyAllowlistUpdates:test_applyAllowlistUpdates_Revert() (gas: 67101) OnRamp_applyAllowlistUpdates:test_applyAllowlistUpdates_Success() (gas: 325983) @@ -535,11 +535,11 @@ OnRamp_forwardFromRouter:test_ShouldIncrementNonceOnlyOnOrdered_Success() (gas: OnRamp_forwardFromRouter:test_ShouldIncrementSeqNumAndNonce_Success() (gas: 213012) OnRamp_forwardFromRouter:test_ShouldStoreLinkFees() (gas: 147026) OnRamp_forwardFromRouter:test_ShouldStoreNonLinkFees() (gas: 161215) -OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3528787) +OnRamp_forwardFromRouter:test_SourceTokenDataTooLarge_Revert() (gas: 3919758) OnRamp_forwardFromRouter:test_UnAllowedOriginalSender_Revert() (gas: 24015) OnRamp_forwardFromRouter:test_UnsupportedToken_Revert() (gas: 75832) OnRamp_forwardFromRouter:test_forwardFromRouter_UnsupportedToken_Revert() (gas: 38588) -OnRamp_forwardFromRouter:test_forwardFromRouter_WithInterception_Success() (gas: 280356) +OnRamp_forwardFromRouter:test_forwardFromRouter_WithInterception_Success() (gas: 281474) OnRamp_getFee:test_EmptyMessage_Success() (gas: 98692) OnRamp_getFee:test_EnforceOutOfOrder_Revert() (gas: 65453) OnRamp_getFee:test_GetFeeOfZeroForTokenMessage_Success() (gas: 87185) @@ -629,7 +629,7 @@ Router_applyRampUpdates:test_OffRampUpdatesWithRouting() (gas: 10750087) Router_applyRampUpdates:test_OnRampDisable() (gas: 56445) Router_applyRampUpdates:test_OnlyOwner_Revert() (gas: 12414) Router_ccipSend:test_CCIPSendLinkFeeNoTokenSuccess_gas() (gas: 131425) -Router_ccipSend:test_CCIPSendLinkFeeOneTokenSuccess_gas() (gas: 221322) +Router_ccipSend:test_CCIPSendLinkFeeOneTokenSuccess_gas() (gas: 221699) Router_ccipSend:test_FeeTokenAmountTooLow_Revert() (gas: 71858) Router_ccipSend:test_InvalidMsgValue() (gas: 32411) Router_ccipSend:test_NativeFeeTokenInsufficientValue() (gas: 69524) @@ -641,7 +641,7 @@ Router_ccipSend:test_UnsupportedDestinationChain_Revert() (gas: 25056) Router_ccipSend:test_WhenNotHealthy_Revert() (gas: 45056) Router_ccipSend:test_WrappedNativeFeeToken_Success() (gas: 194209) Router_ccipSend:test_ccipSend_nativeFeeNoTokenSuccess_gas() (gas: 140674) -Router_ccipSend:test_ccipSend_nativeFeeOneTokenSuccess_gas() (gas: 230506) +Router_ccipSend:test_ccipSend_nativeFeeOneTokenSuccess_gas() (gas: 230883) Router_constructor:test_Constructor_Success() (gas: 13222) Router_getArmProxy:test_getArmProxy() (gas: 10573) Router_getFee:test_GetFeeSupportedChain_Success() (gas: 51934) @@ -680,81 +680,89 @@ TokenAdminRegistry_setPool:test_setPool_Success() (gas: 36267) TokenAdminRegistry_setPool:test_setPool_ZeroAddressRemovesPool_Success() (gas: 30875) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_OnlyAdministrator_Revert() (gas: 18202) TokenAdminRegistry_transferAdminRole:test_transferAdminRole_Success() (gas: 49592) -TokenPoolFactory_constructor:test_constructor_Revert() (gas: 1039441) -TokenPoolFactory_createTokenPool:test_createTokenPoolLockRelease_ExistingToken_predict_Success() (gas: 11591871) -TokenPoolFactory_createTokenPool:test_createTokenPool_BurnFromMintTokenPool_Success() (gas: 5848479) -TokenPoolFactory_createTokenPool:test_createTokenPool_ExistingRemoteToken_AndPredictPool_Success() (gas: 12227675) -TokenPoolFactory_createTokenPool:test_createTokenPool_WithNoExistingRemoteContracts_predict_Success() (gas: 12564436) -TokenPoolFactory_createTokenPool:test_createTokenPool_WithNoExistingTokenOnRemoteChain_Success() (gas: 5701824) -TokenPoolFactory_createTokenPool:test_createTokenPool_WithRemoteTokenAndRemotePool_Success() (gas: 5845002) -TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 1944108) -TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12119) -TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23567) -TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowList_Success() (gas: 178398) +TokenPoolFactory_constructor:test_constructor_Revert() (gas: 1121653) +TokenPoolFactory_createTokenPool:test_createTokenPoolLockRelease_ExistingToken_predict_Success() (gas: 12293466) +TokenPoolFactory_createTokenPool:test_createTokenPool_BurnFromMintTokenPool_Success() (gas: 6290905) +TokenPoolFactory_createTokenPool:test_createTokenPool_ExistingRemoteToken_AndPredictPool_Success() (gas: 13043750) +TokenPoolFactory_createTokenPool:test_createTokenPool_RemoteTokenHasDifferentDecimals_Success() (gas: 13051052) +TokenPoolFactory_createTokenPool:test_createTokenPool_WithNoExistingRemoteContracts_predict_Success() (gas: 13380456) +TokenPoolFactory_createTokenPool:test_createTokenPool_WithNoExistingTokenOnRemoteChain_Success() (gas: 6075765) +TokenPoolFactory_createTokenPool:test_createTokenPool_WithRemoteTokenAndRemotePool_Success() (gas: 6287377) +TokenPoolWithAllowList_applyAllowListUpdates:test_AllowListNotEnabled_Revert() (gas: 2688992) +TokenPoolWithAllowList_applyAllowListUpdates:test_OnlyOwner_Revert() (gas: 12141) +TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowListSkipsZero_Success() (gas: 23589) +TokenPoolWithAllowList_applyAllowListUpdates:test_SetAllowList_Success() (gas: 178451) TokenPoolWithAllowList_getAllowList:test_GetAllowList_Success() (gas: 23929) TokenPoolWithAllowList_getAllowListEnabled:test_GetAllowListEnabled_Success() (gas: 8408) TokenPoolWithAllowList_setRouter:test_SetRouter_Success() (gas: 25005) -TokenPool_applyChainUpdates:test_applyChainUpdates_DisabledNonZeroRateLimit_Revert() (gas: 271914) -TokenPool_applyChainUpdates:test_applyChainUpdates_InvalidRateLimitRate_Revert() (gas: 543487) -TokenPool_applyChainUpdates:test_applyChainUpdates_NonExistentChain_Revert() (gas: 18706) -TokenPool_applyChainUpdates:test_applyChainUpdates_OnlyCallableByOwner_Revert() (gas: 11425) -TokenPool_applyChainUpdates:test_applyChainUpdates_Success() (gas: 480305) -TokenPool_applyChainUpdates:test_applyChainUpdates_ZeroAddressNotAllowed_Revert() (gas: 157716) -TokenPool_constructor:test_ZeroAddressNotAllowed_Revert() (gas: 70445) -TokenPool_constructor:test_immutableFields_Success() (gas: 20718) -TokenPool_getRemotePool:test_getRemotePool_Success() (gas: 274610) -TokenPool_onlyOffRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 277555) -TokenPool_onlyOffRamp:test_ChainNotAllowed_Revert() (gas: 290432) -TokenPool_onlyOffRamp:test_onlyOffRamp_Success() (gas: 350358) -TokenPool_onlyOnRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 277250) -TokenPool_onlyOnRamp:test_ChainNotAllowed_Revert() (gas: 254443) -TokenPool_onlyOnRamp:test_onlyOnRamp_Success() (gas: 305359) -TokenPool_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 17203) -TokenPool_setChainRateLimiterConfig:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 15330) +TokenPoolWithAllowList_setRouter:test_ZeroAddressNotAllowed_Revert() (gas: 10729) +TokenPool_addRemotePool:test_NonExistentChain_Revert() (gas: 14311) +TokenPool_addRemotePool:test_PoolAlreadyAdded_Revert() (gas: 117249) +TokenPool_addRemotePool:test_ZeroLengthAddressNotAllowed_Revert() (gas: 14036) +TokenPool_addRemotePool:test_addRemotePool_Success() (gas: 157117) +TokenPool_applyChainUpdates:test_applyChainUpdates_InvalidRateLimitRate_Revert() (gas: 455575) +TokenPool_applyChainUpdates:test_applyChainUpdates_NonExistentChain_Revert() (gas: 15054) +TokenPool_applyChainUpdates:test_applyChainUpdates_OnlyCallableByOwner_Revert() (gas: 11885) +TokenPool_applyChainUpdates:test_applyChainUpdates_Success() (gas: 592195) +TokenPool_applyChainUpdates:test_applyChainUpdates_ZeroAddressNotAllowed_Revert() (gas: 226494) +TokenPool_calculateLocalAmount:test_calculateLocalAmount() (gas: 84730) +TokenPool_constructor:test_ZeroAddressNotAllowed_Revert() (gas: 71410) +TokenPool_constructor:test_immutableFields_Success() (gas: 21946) +TokenPool_getRemotePool:test_getRemotePools() (gas: 330500) +TokenPool_onlyOffRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 21526) +TokenPool_onlyOffRamp:test_ChainNotAllowed_Revert() (gas: 240488) +TokenPool_onlyOffRamp:test_onlyOffRamp_Success() (gas: 94313) +TokenPool_onlyOnRamp:test_CallerIsNotARampOnRouter_Revert() (gas: 21090) +TokenPool_onlyOnRamp:test_ChainNotAllowed_Revert() (gas: 204288) +TokenPool_onlyOnRamp:test_onlyOnRamp_Success() (gas: 49172) +TokenPool_parseRemoteDecimals:test_parseRemoteDecimals() (gas: 14086) +TokenPool_parseRemoteDecimals:test_parseRemoteDecimals_NoDecimalsDefaultsToLocalDecimals() (gas: 9771) +TokenPool_removeRemotePool:test_InvalidRemotePoolForChain_Revert() (gas: 17499) +TokenPool_removeRemotePool:test_NonExistentChain_Revert() (gas: 14344) +TokenPool_removeRemotePool:test_removeRemotePool_Success() (gas: 188431) +TokenPool_setChainRateLimiterConfig:test_NonExistentChain_Revert() (gas: 17214) +TokenPool_setChainRateLimiterConfig:test_OnlyOwnerOrRateLimitAdmin_Revert() (gas: 15307) TokenPool_setRateLimitAdmin:test_SetRateLimitAdmin_Revert() (gas: 11024) -TokenPool_setRateLimitAdmin:test_SetRateLimitAdmin_Success() (gas: 37584) -TokenPool_setRemotePool:test_setRemotePool_NonExistentChain_Reverts() (gas: 15796) -TokenPool_setRemotePool:test_setRemotePool_OnlyOwner_Reverts() (gas: 13285) -TokenPool_setRemotePool:test_setRemotePool_Success() (gas: 282581) -USDCBridgeMigrator_BurnLockedUSDC:test_PrimaryMechanism_Success() (gas: 135968) -USDCBridgeMigrator_BurnLockedUSDC:test_WhileMigrationPause_Revert() (gas: 109746) -USDCBridgeMigrator_BurnLockedUSDC:test_invalidPermissions_Revert() (gas: 39343) -USDCBridgeMigrator_BurnLockedUSDC:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 309877) -USDCBridgeMigrator_BurnLockedUSDC:test_onLockReleaseMechanism_Success() (gas: 147032) -USDCBridgeMigrator_BurnLockedUSDC:test_onLockReleaseMechanism_thenswitchToPrimary_Success() (gas: 209340) -USDCBridgeMigrator_cancelMigrationProposal:test_cancelExistingCCTPMigrationProposal_Success() (gas: 56190) -USDCBridgeMigrator_cancelMigrationProposal:test_cannotCancelANonExistentMigrationProposal_Revert() (gas: 12691) +TokenPool_setRateLimitAdmin:test_SetRateLimitAdmin_Success() (gas: 37672) +USDCBridgeMigrator_BurnLockedUSDC:test_PrimaryMechanism_Success() (gas: 136004) +USDCBridgeMigrator_BurnLockedUSDC:test_WhileMigrationPause_Revert() (gas: 109849) +USDCBridgeMigrator_BurnLockedUSDC:test_invalidPermissions_Revert() (gas: 39493) +USDCBridgeMigrator_BurnLockedUSDC:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 310057) +USDCBridgeMigrator_BurnLockedUSDC:test_onLockReleaseMechanism_Success() (gas: 147035) +USDCBridgeMigrator_BurnLockedUSDC:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209377) +USDCBridgeMigrator_cancelMigrationProposal:test_cancelExistingCCTPMigrationProposal_Success() (gas: 56155) +USDCBridgeMigrator_cancelMigrationProposal:test_cannotCancelANonExistentMigrationProposal_Revert() (gas: 12669) USDCBridgeMigrator_excludeTokensFromBurn:test_excludeTokensWhenNoMigrationProposalPending_Revert() (gas: 13579) USDCBridgeMigrator_proposeMigration:test_ChainNotUsingLockRelease_Revert() (gas: 15765) -USDCBridgeMigrator_provideLiquidity:test_PrimaryMechanism_Success() (gas: 135951) -USDCBridgeMigrator_provideLiquidity:test_WhileMigrationPause_Revert() (gas: 109768) -USDCBridgeMigrator_provideLiquidity:test_cannotModifyLiquidityWithoutPermissions_Revert() (gas: 13378) -USDCBridgeMigrator_provideLiquidity:test_cannotProvideLiquidityWhenMigrationProposalPending_Revert() (gas: 67436) -USDCBridgeMigrator_provideLiquidity:test_cannotProvideLiquidity_AfterMigration_Revert() (gas: 313717) -USDCBridgeMigrator_provideLiquidity:test_invalidPermissions_Revert() (gas: 39343) -USDCBridgeMigrator_provideLiquidity:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 309877) -USDCBridgeMigrator_provideLiquidity:test_onLockReleaseMechanism_Success() (gas: 147077) -USDCBridgeMigrator_provideLiquidity:test_onLockReleaseMechanism_thenswitchToPrimary_Success() (gas: 209376) -USDCBridgeMigrator_releaseOrMint:test_OnLockReleaseMechanism_Success() (gas: 216971) -USDCBridgeMigrator_releaseOrMint:test_WhileMigrationPause_Revert() (gas: 113505) -USDCBridgeMigrator_releaseOrMint:test_incomingMessageWithPrimaryMechanism() (gas: 269164) -USDCBridgeMigrator_releaseOrMint:test_unstickManualTxAfterMigration_destChain_Success() (gas: 156100) -USDCBridgeMigrator_releaseOrMint:test_unstickManualTxAfterMigration_homeChain_Success() (gas: 516312) -USDCBridgeMigrator_updateChainSelectorMechanism:test_PrimaryMechanism_Success() (gas: 135968) -USDCBridgeMigrator_updateChainSelectorMechanism:test_WhileMigrationPause_Revert() (gas: 109746) -USDCBridgeMigrator_updateChainSelectorMechanism:test_cannotRevertChainMechanism_afterMigration_Revert() (gas: 313315) -USDCBridgeMigrator_updateChainSelectorMechanism:test_invalidPermissions_Revert() (gas: 39321) -USDCBridgeMigrator_updateChainSelectorMechanism:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 309877) -USDCBridgeMigrator_updateChainSelectorMechanism:test_onLockReleaseMechanism_Success() (gas: 147032) -USDCBridgeMigrator_updateChainSelectorMechanism:test_onLockReleaseMechanism_thenswitchToPrimary_Success() (gas: 209340) -USDCTokenPool__validateMessage:test_ValidateInvalidMessage_Revert() (gas: 25854) -USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35526) -USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 30257) -USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 133526) -USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 478407) -USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 268879) -USDCTokenPool_releaseOrMint:test_TokenMaxCapacityExceeded_Revert() (gas: 51026) -USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 99086) +USDCBridgeMigrator_provideLiquidity:test_PrimaryMechanism_Success() (gas: 135986) +USDCBridgeMigrator_provideLiquidity:test_WhileMigrationPause_Revert() (gas: 109871) +USDCBridgeMigrator_provideLiquidity:test_cannotModifyLiquidityWithoutPermissions_Revert() (gas: 13379) +USDCBridgeMigrator_provideLiquidity:test_cannotProvideLiquidityWhenMigrationProposalPending_Revert() (gas: 67417) +USDCBridgeMigrator_provideLiquidity:test_cannotProvideLiquidity_AfterMigration_Revert() (gas: 313898) +USDCBridgeMigrator_provideLiquidity:test_invalidPermissions_Revert() (gas: 39493) +USDCBridgeMigrator_provideLiquidity:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 310057) +USDCBridgeMigrator_provideLiquidity:test_onLockReleaseMechanism_Success() (gas: 147080) +USDCBridgeMigrator_provideLiquidity:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209395) +USDCBridgeMigrator_releaseOrMint:test_OnLockReleaseMechanism_Success() (gas: 213160) +USDCBridgeMigrator_releaseOrMint:test_WhileMigrationPause_Revert() (gas: 109679) +USDCBridgeMigrator_releaseOrMint:test_incomingMessageWithPrimaryMechanism() (gas: 265963) +USDCBridgeMigrator_releaseOrMint:test_unstickManualTxAfterMigration_destChain_Success() (gas: 150538) +USDCBridgeMigrator_releaseOrMint:test_unstickManualTxAfterMigration_homeChain_Success() (gas: 511783) +USDCBridgeMigrator_updateChainSelectorMechanism:test_PrimaryMechanism_Success() (gas: 136004) +USDCBridgeMigrator_updateChainSelectorMechanism:test_WhileMigrationPause_Revert() (gas: 109849) +USDCBridgeMigrator_updateChainSelectorMechanism:test_cannotRevertChainMechanism_afterMigration_Revert() (gas: 313496) +USDCBridgeMigrator_updateChainSelectorMechanism:test_invalidPermissions_Revert() (gas: 39471) +USDCBridgeMigrator_updateChainSelectorMechanism:test_lockOrBurn_then_BurnInCCTPMigration_Success() (gas: 310057) +USDCBridgeMigrator_updateChainSelectorMechanism:test_onLockReleaseMechanism_Success() (gas: 147035) +USDCBridgeMigrator_updateChainSelectorMechanism:test_onLockReleaseMechanism_thenSwitchToPrimary_Success() (gas: 209448) +USDCTokenPool__validateMessage:test_ValidateInvalidMessage_Revert() (gas: 26049) +USDCTokenPool_lockOrBurn:test_CallerIsNotARampOnRouter_Revert() (gas: 35369) +USDCTokenPool_lockOrBurn:test_LockOrBurnWithAllowList_Revert() (gas: 29947) +USDCTokenPool_lockOrBurn:test_LockOrBurn_Success() (gas: 133581) +USDCTokenPool_lockOrBurn:test_UnknownDomain_Revert() (gas: 433813) +USDCTokenPool_releaseOrMint:test_ReleaseOrMintRealTx_Success() (gas: 265825) +USDCTokenPool_releaseOrMint:test_TokenMaxCapacityExceeded_Revert() (gas: 47231) +USDCTokenPool_releaseOrMint:test_UnlockingUSDCFailed_Revert() (gas: 95315) USDCTokenPool_setDomains:test_InvalidDomain_Revert() (gas: 66437) USDCTokenPool_setDomains:test_OnlyOwner_Revert() (gas: 11314) USDCTokenPool_supportsInterface:test_SupportsInterface_Success() (gas: 10107) \ No newline at end of file diff --git a/contracts/gas-snapshots/l2ep.gas-snapshot b/contracts/gas-snapshots/l2ep.gas-snapshot index e9e5a42878b..643127b6212 100644 --- a/contracts/gas-snapshots/l2ep.gas-snapshot +++ b/contracts/gas-snapshots/l2ep.gas-snapshot @@ -1,142 +1,142 @@ -ArbitrumCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 37586) -ArbitrumCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 12963) -ArbitrumCrossDomainForwarder_Constructor:test_InitialState() (gas: 22141) -ArbitrumCrossDomainForwarder_Forward:test_Forward() (gas: 47867) -ArbitrumCrossDomainForwarder_Forward:test_ForwardRevert() (gas: 22174) -ArbitrumCrossDomainForwarder_Forward:test_NotCallableByUnknownAddress() (gas: 16099) -ArbitrumCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 41453) -ArbitrumCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 19290) -ArbitrumCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 18659) -ArbitrumCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 13242) -ArbitrumCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 37586) -ArbitrumCrossDomainGovernor_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 12963) -ArbitrumCrossDomainGovernor_Constructor:test_InitialState() (gas: 22164) -ArbitrumCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 50003) -ArbitrumCrossDomainGovernor_Forward:test_Forward() (gas: 47918) -ArbitrumCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 24296) -ArbitrumCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 18233) -ArbitrumCrossDomainGovernor_ForwardDelegate:test_BubbleUpRevert() (gas: 19361) -ArbitrumCrossDomainGovernor_ForwardDelegate:test_CallableByCrossDomainMessengerAddressOrL1Owner() (gas: 60874) -ArbitrumCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 63003) -ArbitrumCrossDomainGovernor_ForwardDelegate:test_NotCallableByUnknownAddress() (gas: 18288) -ArbitrumCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 64368) -ArbitrumCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 41453) -ArbitrumCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 19290) -ArbitrumCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 18659) -ArbitrumCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 13242) -ArbitrumSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 104880) -ArbitrumSequencerUptimeFeed_AggregatorV3Interface:test_Return0WhenRoundDoesNotExistYet() (gas: 19973) -ArbitrumSequencerUptimeFeed_Constants:test_InitialState() (gas: 8496) -ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 604370) -ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574432) -ArbitrumSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 99663) -ArbitrumSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 15453) -ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 114637) -ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 114720) -ArbitrumValidator_Validate:test_PostSequencerOffline() (gas: 69068) -OptimismCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47162) -OptimismCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22163) -OptimismCrossDomainForwarder_Constructor:test_InitialState() (gas: 21976) -OptimismCrossDomainForwarder_Forward:test_Forward() (gas: 58281) -OptimismCrossDomainForwarder_Forward:test_ForwardRevert() (gas: 32583) -OptimismCrossDomainForwarder_Forward:test_NotCallableByUnknownAddress() (gas: 13910) -OptimismCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 48945) -OptimismCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28768) -OptimismCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16470) -OptimismCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11053) -OptimismCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47162) -OptimismCrossDomainGovernor_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22163) -OptimismCrossDomainGovernor_Constructor:test_InitialState() (gas: 21999) -OptimismCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 47846) -OptimismCrossDomainGovernor_Forward:test_Forward() (gas: 58352) -OptimismCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 32619) -OptimismCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 16047) -OptimismCrossDomainGovernor_ForwardDelegate:test_BubbleUpRevert() (gas: 29170) -OptimismCrossDomainGovernor_ForwardDelegate:test_CallableByCrossDomainMessengerAddressOrL1Owner() (gas: 72942) -OptimismCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 72947) -OptimismCrossDomainGovernor_ForwardDelegate:test_NotCallableByUnknownAddress() (gas: 16102) -OptimismCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 76156) -OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 48945) -OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28768) -OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16470) -OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11053) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72382) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17653) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17893) -OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17642) -OptimismSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22028) -OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601594) -OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574437) -OptimismSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67861) -OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13118) -OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23536) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77316) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 96170) -OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 96253) -OptimismValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18649) -OptimismValidator_Validate:test_PostSequencerOffline() (gas: 74813) -OptimismValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 74847) -OptimismValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15571) -ScrollCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47252) -ScrollCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22215) -ScrollCrossDomainForwarder_Constructor:test_InitialState() (gas: 21652) -ScrollCrossDomainForwarder_Forward:test_Forward() (gas: 58348) -ScrollCrossDomainForwarder_Forward:test_ForwardRevert() (gas: 32641) -ScrollCrossDomainForwarder_Forward:test_NotCallableByUnknownAddress() (gas: 13910) -ScrollCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 49011) -ScrollCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28828) -ScrollCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16470) -ScrollCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11053) -ScrollCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47252) -ScrollCrossDomainGovernor_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22215) -ScrollCrossDomainGovernor_Constructor:test_InitialState() (gas: 21675) -ScrollCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 47841) -ScrollCrossDomainGovernor_Forward:test_Forward() (gas: 58414) -ScrollCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 32674) -ScrollCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 16044) -ScrollCrossDomainGovernor_ForwardDelegate:test_BubbleUpRevert() (gas: 29231) -ScrollCrossDomainGovernor_ForwardDelegate:test_CallableByCrossDomainMessengerAddressOrL1Owner() (gas: 73009) -ScrollCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 73014) -ScrollCrossDomainGovernor_ForwardDelegate:test_NotCallableByUnknownAddress() (gas: 16099) -ScrollCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 76224) -ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 49011) -ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28828) -ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16470) -ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11053) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72405) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17653) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17893) -ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17642) -ScrollSequencerUptimeFeed_Constructor:test_InitialState() (gas: 173913) -ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601594) -ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574437) -ScrollSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67907) -ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13118) -ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23536) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77362) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 96216) -ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 96299) -ScrollValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18783) -ScrollValidator_Validate:test_PostSequencerOffline() (gas: 78349) -ScrollValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 78389) -ScrollValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15571) -ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 67184) -ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17653) -ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17893) -ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17642) -ZKSyncSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22032) -ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 601614) -ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 574443) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 61936) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13064) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 71428) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 90253) -ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 90336) -ZKSyncValidator_Constructor:test_ConstructingRevertedWithInvalidChainId() (gas: 103748) -ZKSyncValidator_Constructor:test_ConstructingRevertedWithZeroL1BridgeAddress() (gas: 81463) -ZKSyncValidator_Constructor:test_ConstructingRevertedWithZeroL2UpdateFeedAddress() (gas: 81475) -ZKSyncValidator_GetChainId:test_CorrectlyGetsTheChainId() (gas: 8350) -ZKSyncValidator_GetSetL2GasPerPubdataByteLimit:test_CorrectlyGetsAndUpdatesTheGasPerPubdataByteLimit() (gas: 18909) -ZKSyncValidator_Validate:test_PostSequencerOffline() (gas: 52260) -ZKSyncValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 52327) -ZKSyncValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15638) \ No newline at end of file +ArbitrumCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 37567) +ArbitrumCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 12954) +ArbitrumCrossDomainForwarder_Constructor:test_InitialState() (gas: 22111) +ArbitrumCrossDomainForwarder_Forward:test_Forward() (gas: 47818) +ArbitrumCrossDomainForwarder_Forward:test_ForwardRevert() (gas: 22147) +ArbitrumCrossDomainForwarder_Forward:test_NotCallableByUnknownAddress() (gas: 16083) +ArbitrumCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 41439) +ArbitrumCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 19274) +ArbitrumCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 18644) +ArbitrumCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 13232) +ArbitrumCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 37567) +ArbitrumCrossDomainGovernor_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 12954) +ArbitrumCrossDomainGovernor_Constructor:test_InitialState() (gas: 22134) +ArbitrumCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 49953) +ArbitrumCrossDomainGovernor_Forward:test_Forward() (gas: 47869) +ArbitrumCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 24268) +ArbitrumCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 18216) +ArbitrumCrossDomainGovernor_ForwardDelegate:test_BubbleUpRevert() (gas: 19338) +ArbitrumCrossDomainGovernor_ForwardDelegate:test_CallableByCrossDomainMessengerAddressOrL1Owner() (gas: 60787) +ArbitrumCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 62915) +ArbitrumCrossDomainGovernor_ForwardDelegate:test_NotCallableByUnknownAddress() (gas: 18271) +ArbitrumCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 64276) +ArbitrumCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 41439) +ArbitrumCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 19274) +ArbitrumCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 18644) +ArbitrumCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 13232) +ArbitrumSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 104766) +ArbitrumSequencerUptimeFeed_AggregatorV3Interface:test_Return0WhenRoundDoesNotExistYet() (gas: 19945) +ArbitrumSequencerUptimeFeed_Constants:test_InitialState() (gas: 8492) +ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 592246) +ArbitrumSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 562331) +ArbitrumSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 99593) +ArbitrumSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 15442) +ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 114527) +ArbitrumSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 114610) +ArbitrumValidator_Validate:test_PostSequencerOffline() (gas: 69009) +OptimismCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47110) +OptimismCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22135) +OptimismCrossDomainForwarder_Constructor:test_InitialState() (gas: 21947) +OptimismCrossDomainForwarder_Forward:test_Forward() (gas: 58213) +OptimismCrossDomainForwarder_Forward:test_ForwardRevert() (gas: 32533) +OptimismCrossDomainForwarder_Forward:test_NotCallableByUnknownAddress() (gas: 13895) +OptimismCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 48912) +OptimismCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28733) +OptimismCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16456) +OptimismCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11044) +OptimismCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47110) +OptimismCrossDomainGovernor_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22135) +OptimismCrossDomainGovernor_Constructor:test_InitialState() (gas: 21970) +OptimismCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 47797) +OptimismCrossDomainGovernor_Forward:test_Forward() (gas: 58284) +OptimismCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 32569) +OptimismCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 16031) +OptimismCrossDomainGovernor_ForwardDelegate:test_BubbleUpRevert() (gas: 29128) +OptimismCrossDomainGovernor_ForwardDelegate:test_CallableByCrossDomainMessengerAddressOrL1Owner() (gas: 72836) +OptimismCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 72841) +OptimismCrossDomainGovernor_ForwardDelegate:test_NotCallableByUnknownAddress() (gas: 16086) +OptimismCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 76045) +OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 48912) +OptimismCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28733) +OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16456) +OptimismCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11044) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72286) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17639) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17875) +OptimismSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17628) +OptimismSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22002) +OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 589475) +OptimismSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 562336) +OptimismSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67804) +OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13109) +OptimismSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23523) +OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77205) +OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 96089) +OptimismSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 96172) +OptimismValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18636) +OptimismValidator_Validate:test_PostSequencerOffline() (gas: 74764) +OptimismValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 74798) +OptimismValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15556) +ScrollCrossDomainForwarder_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47196) +ScrollCrossDomainForwarder_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22185) +ScrollCrossDomainForwarder_Constructor:test_InitialState() (gas: 21623) +ScrollCrossDomainForwarder_Forward:test_Forward() (gas: 58277) +ScrollCrossDomainForwarder_Forward:test_ForwardRevert() (gas: 32589) +ScrollCrossDomainForwarder_Forward:test_NotCallableByUnknownAddress() (gas: 13895) +ScrollCrossDomainForwarder_TransferL1Ownership:test_CallableByL1Owner() (gas: 48975) +ScrollCrossDomainForwarder_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28791) +ScrollCrossDomainForwarder_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16456) +ScrollCrossDomainForwarder_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11044) +ScrollCrossDomainGovernor_AcceptL1Ownership:test_CallableByPendingL1Owner() (gas: 47196) +ScrollCrossDomainGovernor_AcceptL1Ownership:test_NotCallableByNonPendingOwners() (gas: 22185) +ScrollCrossDomainGovernor_Constructor:test_InitialState() (gas: 21646) +ScrollCrossDomainGovernor_Forward:test_CallableByL2Owner() (gas: 47792) +ScrollCrossDomainGovernor_Forward:test_Forward() (gas: 58343) +ScrollCrossDomainGovernor_Forward:test_ForwardRevert() (gas: 32622) +ScrollCrossDomainGovernor_Forward:test_NotCallableByUnknownAddress() (gas: 16028) +ScrollCrossDomainGovernor_ForwardDelegate:test_BubbleUpRevert() (gas: 29186) +ScrollCrossDomainGovernor_ForwardDelegate:test_CallableByCrossDomainMessengerAddressOrL1Owner() (gas: 72900) +ScrollCrossDomainGovernor_ForwardDelegate:test_CallableByL2Owner() (gas: 72905) +ScrollCrossDomainGovernor_ForwardDelegate:test_NotCallableByUnknownAddress() (gas: 16083) +ScrollCrossDomainGovernor_ForwardDelegate:test_RevertsBatchWhenOneCallFails() (gas: 76110) +ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1Owner() (gas: 48975) +ScrollCrossDomainGovernor_TransferL1Ownership:test_CallableByL1OwnerOrZeroAddress() (gas: 28791) +ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByL2Owner() (gas: 16456) +ScrollCrossDomainGovernor_TransferL1Ownership:test_NotCallableByNonOwners() (gas: 11044) +ScrollSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 72309) +ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17639) +ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17875) +ScrollSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17628) +ScrollSequencerUptimeFeed_Constructor:test_InitialState() (gas: 174353) +ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 589475) +ScrollSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 562336) +ScrollSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 67850) +ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13109) +ScrollSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddrAndNotL1SenderAddr() (gas: 23523) +ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 77251) +ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 96135) +ScrollSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 96218) +ScrollValidator_SetGasLimit:test_CorrectlyUpdatesTheGasLimit() (gas: 18770) +ScrollValidator_Validate:test_PostSequencerOffline() (gas: 78299) +ScrollValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 78339) +ScrollValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15556) +ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_AggregatorV3Interface() (gas: 67090) +ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetAnswerWhenRoundDoesNotExistYet() (gas: 17639) +ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetRoundDataWhenRoundDoesNotExistYet() (gas: 17875) +ZKSyncSequencerUptimeFeed_AggregatorV3Interface:test_RevertGetTimestampWhenRoundDoesNotExistYet() (gas: 17628) +ZKSyncSequencerUptimeFeed_Constructor:test_InitialState() (gas: 22006) +ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceAllowReadsIfConsumingContractIsWhitelisted() (gas: 589495) +ZKSyncSequencerUptimeFeed_ProtectReadsOnAggregatorV2V3InterfaceFunctions:test_AggregatorV2V3InterfaceDisallowReadsIfConsumingContractIsNotWhitelisted() (gas: 562342) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_IgnoreOutOfOrderUpdates() (gas: 61883) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_RevertIfNotL2CrossDomainMessengerAddr() (gas: 13055) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenNoChange() (gas: 71321) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndNoTimeChange() (gas: 90176) +ZKSyncSequencerUptimeFeed_UpdateStatus:test_UpdateStatusWhenStatusChangeAndTimeChange() (gas: 90259) +ZKSyncValidator_Constructor:test_ConstructingRevertedWithInvalidChainId() (gas: 104069) +ZKSyncValidator_Constructor:test_ConstructingRevertedWithZeroL1BridgeAddress() (gas: 81784) +ZKSyncValidator_Constructor:test_ConstructingRevertedWithZeroL2UpdateFeedAddress() (gas: 81796) +ZKSyncValidator_GetChainId:test_CorrectlyGetsTheChainId() (gas: 8346) +ZKSyncValidator_GetSetL2GasPerPubdataByteLimit:test_CorrectlyGetsAndUpdatesTheGasPerPubdataByteLimit() (gas: 18896) +ZKSyncValidator_Validate:test_PostSequencerOffline() (gas: 52210) +ZKSyncValidator_Validate:test_PostSequencerStatusWhenThereIsNotStatusChange() (gas: 52279) +ZKSyncValidator_Validate:test_RevertsIfCalledByAnAccountWithNoAccess() (gas: 15623) \ No newline at end of file diff --git a/contracts/gas-snapshots/liquiditymanager.gas-snapshot b/contracts/gas-snapshots/liquiditymanager.gas-snapshot index 435e79b002e..bdbfc60452b 100644 --- a/contracts/gas-snapshots/liquiditymanager.gas-snapshot +++ b/contracts/gas-snapshots/liquiditymanager.gas-snapshot @@ -3,14 +3,14 @@ LiquidityManager_addLiquidity:test_addLiquiditySuccess() (gas: 279198) LiquidityManager_rebalanceLiquidity:test_InsufficientLiquidityReverts() (gas: 206764) LiquidityManager_rebalanceLiquidity:test_InvalidRemoteChainReverts() (gas: 192374) LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess() (gas: 9141798) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 8942122) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 8937262) -LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 8865000) -LiquidityManager_rebalanceLiquidity:test_rebalanceLiquiditySuccess() (gas: 382946) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPoolsSuccess_AlreadyFinalized() (gas: 9246772) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_MultiStageFinalization() (gas: 9241912) +LiquidityManager_rebalanceLiquidity:test_rebalanceBetweenPools_NativeRewrap() (gas: 9169653) +LiquidityManager_rebalanceLiquidity:test_rebalanceLiquiditySuccess() (gas: 382928) LiquidityManager_receive:test_receive_success() (gas: 21182) LiquidityManager_removeLiquidity:test_InsufficientLiquidityReverts() (gas: 184959) LiquidityManager_removeLiquidity:test_OnlyFinanceRoleReverts() (gas: 10872) -LiquidityManager_removeLiquidity:test_removeLiquiditySuccess() (gas: 236379) +LiquidityManager_removeLiquidity:test_removeLiquiditySuccess() (gas: 236361) LiquidityManager_setCrossChainRebalancer:test_OnlyOwnerReverts() (gas: 17005) LiquidityManager_setCrossChainRebalancer:test_ZeroAddressReverts() (gas: 21669) LiquidityManager_setCrossChainRebalancer:test_ZeroChainSelectorReverts() (gas: 13099) @@ -19,7 +19,7 @@ LiquidityManager_setFinanceRole:test_OnlyOwnerReverts() (gas: 10987) LiquidityManager_setFinanceRole:test_setFinanceRoleSuccess() (gas: 21836) LiquidityManager_setLocalLiquidityContainer:test_OnlyOwnerReverts() (gas: 11030) LiquidityManager_setLocalLiquidityContainer:test_ReverstWhen_CalledWithTheZeroAddress() (gas: 10621) -LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3479905) +LiquidityManager_setLocalLiquidityContainer:test_setLocalLiquidityContainerSuccess() (gas: 3784709) LiquidityManager_setMinimumLiquidity:test_OnlyOwnerReverts() (gas: 10925) LiquidityManager_setMinimumLiquidity:test_setMinimumLiquiditySuccess() (gas: 36389) LiquidityManager_withdrawERC20:test_withdrawERC20Reverts() (gas: 180396) diff --git a/contracts/gas-snapshots/shared.gas-snapshot b/contracts/gas-snapshots/shared.gas-snapshot index fc8096cbb5d..54475701734 100644 --- a/contracts/gas-snapshots/shared.gas-snapshot +++ b/contracts/gas-snapshots/shared.gas-snapshot @@ -1,111 +1,111 @@ -AuthorizedCallers_applyAuthorizedCallerUpdates:test_AddAndRemove_Success() (gas: 124942) -AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyAdd_Success() (gas: 132869) -AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyCallableByOwner_Revert() (gas: 12238) -AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyRemove_Success() (gas: 44907) -AuthorizedCallers_applyAuthorizedCallerUpdates:test_RemoveThenAdd_Success() (gas: 56991) -AuthorizedCallers_applyAuthorizedCallerUpdates:test_SkipRemove_Success() (gas: 31961) -AuthorizedCallers_applyAuthorizedCallerUpdates:test_ZeroAddressNotAllowed_Revert() (gas: 64413) -AuthorizedCallers_constructor:test_ZeroAddressNotAllowed_Revert() (gas: 64390) -AuthorizedCallers_constructor:test_constructor_Success() (gas: 674931) -BurnMintERC20_approve:test_approve() (gas: 57652) -BurnMintERC20_burn:test_BasicBurn() (gas: 153607) -BurnMintERC20_burnFrom:test_BurnFrom() (gas: 57995) -BurnMintERC20_burnFromAlias:test_burn() (gas: 58039) -BurnMintERC20_constructor:test_Constructor() (gas: 1694831) -BurnMintERC20_getCCIPAdmin:test_getCCIPAdmin() (gas: 10548) -BurnMintERC20_getCCIPAdmin:test_setCCIPAdmin() (gas: 21590) -BurnMintERC20_grantMintAndBurnRoles:test_GrantMintAndBurnRoles() (gas: 79142) -BurnMintERC20_mint:test_mint() (gas: 101849) -BurnMintERC20_supportsInterface:test_SupportsInterface() (gas: 11218) -BurnMintERC20_transfer:test_transfer() (gas: 42338) -BurnMintERC677_approve:testApproveSuccess() (gas: 55512) -BurnMintERC677_approve:testInvalidAddressReverts() (gas: 10663) -BurnMintERC677_burn:testBasicBurnSuccess() (gas: 172100) -BurnMintERC677_burn:testBurnFromZeroAddressReverts() (gas: 47201) -BurnMintERC677_burn:testExceedsBalanceReverts() (gas: 21841) -BurnMintERC677_burn:testSenderNotBurnerReverts() (gas: 13359) -BurnMintERC677_burnFrom:testBurnFromSuccess() (gas: 57959) -BurnMintERC677_burnFrom:testExceedsBalanceReverts() (gas: 35864) -BurnMintERC677_burnFrom:testInsufficientAllowanceReverts() (gas: 21849) -BurnMintERC677_burnFrom:testSenderNotBurnerReverts() (gas: 13359) -BurnMintERC677_burnFromAlias:testBurnFromSuccess() (gas: 57985) -BurnMintERC677_burnFromAlias:testExceedsBalanceReverts() (gas: 35880) -BurnMintERC677_burnFromAlias:testInsufficientAllowanceReverts() (gas: 21869) -BurnMintERC677_burnFromAlias:testSenderNotBurnerReverts() (gas: 13379) -BurnMintERC677_constructor:testConstructorSuccess() (gas: 1672812) -BurnMintERC677_decreaseApproval:testDecreaseApprovalSuccess() (gas: 31069) -BurnMintERC677_grantMintAndBurnRoles:testGrantMintAndBurnRolesSuccess() (gas: 121324) -BurnMintERC677_grantRole:testGrantBurnAccessSuccess() (gas: 53442) -BurnMintERC677_grantRole:testGrantManySuccess() (gas: 937759) -BurnMintERC677_grantRole:testGrantMintAccessSuccess() (gas: 94323) -BurnMintERC677_increaseApproval:testIncreaseApprovalSuccess() (gas: 44076) -BurnMintERC677_mint:testBasicMintSuccess() (gas: 149699) -BurnMintERC677_mint:testMaxSupplyExceededReverts() (gas: 50363) -BurnMintERC677_mint:testSenderNotMinterReverts() (gas: 11195) -BurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 12476) -BurnMintERC677_transfer:testInvalidAddressReverts() (gas: 10639) -BurnMintERC677_transfer:testTransferSuccess() (gas: 42299) -CallWithExactGas__callWithExactGas:test_CallWithExactGasReceiverErrorSuccess() (gas: 65949) -CallWithExactGas__callWithExactGas:test_CallWithExactGasSafeReturnDataExactGas() (gas: 18324) -CallWithExactGas__callWithExactGas:test_NoContractReverts() (gas: 11559) -CallWithExactGas__callWithExactGas:test_NoGasForCallExactCheckReverts() (gas: 15788) -CallWithExactGas__callWithExactGas:test_NotEnoughGasForCallReverts() (gas: 16241) -CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractExactGasSuccess() (gas: 20073) -CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractReceiverErrorSuccess() (gas: 66461) -CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoContractSuccess() (gas: 12962) -CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoGasForCallExactCheckReturnFalseSuccess() (gas: 13005) -CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NotEnoughGasForCallReturnsFalseSuccess() (gas: 13317) -CallWithExactGas__callWithExactGasSafeReturnData:test_CallWithExactGasSafeReturnDataExactGas() (gas: 20331) -CallWithExactGas__callWithExactGasSafeReturnData:test_NoContractReverts() (gas: 13939) -CallWithExactGas__callWithExactGasSafeReturnData:test_NoGasForCallExactCheckReverts() (gas: 16139) -CallWithExactGas__callWithExactGasSafeReturnData:test_NotEnoughGasForCallReverts() (gas: 16547) -CallWithExactGas__callWithExactGasSafeReturnData:test_callWithExactGasSafeReturnData_ThrowOOGError_Revert() (gas: 36755) -EnumerableMapAddresses_at:testAtSuccess() (gas: 95086) -EnumerableMapAddresses_at:testBytes32AtSuccess() (gas: 94855) -EnumerableMapAddresses_at:testBytesAtSuccess() (gas: 96542) -EnumerableMapAddresses_contains:testBytes32ContainsSuccess() (gas: 93518) -EnumerableMapAddresses_contains:testBytesContainsSuccess() (gas: 93990) -EnumerableMapAddresses_contains:testContainsSuccess() (gas: 93696) -EnumerableMapAddresses_get:testBytes32GetSuccess() (gas: 94256) -EnumerableMapAddresses_get:testBytesGetSuccess() (gas: 95945) -EnumerableMapAddresses_get:testGetSuccess() (gas: 94431) -EnumerableMapAddresses_get_errorMessage:testBytesGetErrorMessageSuccess() (gas: 95878) -EnumerableMapAddresses_get_errorMessage:testGetErrorMessageSuccess() (gas: 94489) -EnumerableMapAddresses_length:testBytes32LengthSuccess() (gas: 72445) -EnumerableMapAddresses_length:testBytesLengthSuccess() (gas: 73064) -EnumerableMapAddresses_length:testLengthSuccess() (gas: 72623) -EnumerableMapAddresses_remove:testBytes32RemoveSuccess() (gas: 73462) -EnumerableMapAddresses_remove:testBytesRemoveSuccess() (gas: 74249) -EnumerableMapAddresses_remove:testRemoveSuccess() (gas: 73686) -EnumerableMapAddresses_set:testBytes32SetSuccess() (gas: 94496) -EnumerableMapAddresses_set:testBytesSetSuccess() (gas: 95428) -EnumerableMapAddresses_set:testSetSuccess() (gas: 94663) -EnumerableMapAddresses_tryGet:testBytes32TryGetSuccess() (gas: 94622) -EnumerableMapAddresses_tryGet:testBytesTryGetSuccess() (gas: 96345) -EnumerableMapAddresses_tryGet:testTryGetSuccess() (gas: 94893) -OpStackBurnMintERC677_constructor:testConstructorSuccess() (gas: 1743682) -OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 291483) -OpStackBurnMintERC677_interfaceCompatibility:testMintCompatibility() (gas: 137957) -OpStackBurnMintERC677_interfaceCompatibility:testStaticFunctionsCompatibility() (gas: 13781) -OpStackBurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 12752) -Ownable2Step_acceptOwnership:test_acceptOwnership_MustBeProposedOwner_reverts() (gas: 10360) -Ownable2Step_acceptOwnership:test_acceptOwnership_success() (gas: 31088) -Ownable2Step_constructor:test_constructor_OwnerCannotBeZero_reverts() (gas: 35858) -Ownable2Step_constructor:test_constructor_success() (gas: 10428) -Ownable2Step_onlyOwner:test_onlyOwner_OnlyCallableByOwner_reverts() (gas: 10754) -Ownable2Step_onlyOwner:test_onlyOwner_success() (gas: 7506) -Ownable2Step_transferOwnership:test_transferOwnership_CannotTransferToSelf_reverts() (gas: 10501) -Ownable2Step_transferOwnership:test_transferOwnership_success() (gas: 30140) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_EmptySubset_Reverts() (gas: 5208) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_EmptySuperset_Reverts() (gas: 4535) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_HasDuplicates_Reverts() (gas: 7761) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_NotASubset_Reverts() (gas: 11733) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SingleElementSubset() (gas: 3922) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SingleElementSubsetAndSuperset_Equal() (gas: 1464) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SingleElementSubsetAndSuperset_NotEqual_Reverts() (gas: 6172) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SubsetEqualsSuperset_NoRevert() (gas: 7859) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SubsetLargerThanSuperset_Reverts() (gas: 15410) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SupersetHasDuplicates_Reverts() (gas: 8790) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_UnsortedSubset_Reverts() (gas: 7128) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_UnsortedSuperset_Reverts() (gas: 8970) -SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_ValidSubset_Success() (gas: 5671) \ No newline at end of file +AuthorizedCallers_applyAuthorizedCallerUpdates:test_AddAndRemove_Success() (gas: 124848) +AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyAdd_Success() (gas: 132793) +AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyCallableByOwner_Revert() (gas: 12218) +AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyRemove_Success() (gas: 44833) +AuthorizedCallers_applyAuthorizedCallerUpdates:test_RemoveThenAdd_Success() (gas: 56901) +AuthorizedCallers_applyAuthorizedCallerUpdates:test_SkipRemove_Success() (gas: 31911) +AuthorizedCallers_applyAuthorizedCallerUpdates:test_ZeroAddressNotAllowed_Revert() (gas: 64612) +AuthorizedCallers_constructor:test_ZeroAddressNotAllowed_Revert() (gas: 64589) +AuthorizedCallers_constructor:test_constructor_Success() (gas: 663486) +BurnMintERC20_approve:test_approve() (gas: 57609) +BurnMintERC20_burn:test_BasicBurn() (gas: 153528) +BurnMintERC20_burnFrom:test_BurnFrom() (gas: 57965) +BurnMintERC20_burnFromAlias:test_burn() (gas: 58009) +BurnMintERC20_constructor:test_Constructor() (gas: 1680059) +BurnMintERC20_getCCIPAdmin:test_getCCIPAdmin() (gas: 10544) +BurnMintERC20_getCCIPAdmin:test_setCCIPAdmin() (gas: 21562) +BurnMintERC20_grantMintAndBurnRoles:test_GrantMintAndBurnRoles() (gas: 79089) +BurnMintERC20_mint:test_mint() (gas: 101815) +BurnMintERC20_supportsInterface:test_SupportsInterface() (gas: 11202) +BurnMintERC20_transfer:test_transfer() (gas: 42318) +BurnMintERC677_approve:testApproveSuccess() (gas: 55477) +BurnMintERC677_approve:testInvalidAddressReverts() (gas: 10653) +BurnMintERC677_burn:testBasicBurnSuccess() (gas: 172022) +BurnMintERC677_burn:testBurnFromZeroAddressReverts() (gas: 47166) +BurnMintERC677_burn:testExceedsBalanceReverts() (gas: 21816) +BurnMintERC677_burn:testSenderNotBurnerReverts() (gas: 13346) +BurnMintERC677_burnFrom:testBurnFromSuccess() (gas: 57928) +BurnMintERC677_burnFrom:testExceedsBalanceReverts() (gas: 35838) +BurnMintERC677_burnFrom:testInsufficientAllowanceReverts() (gas: 21824) +BurnMintERC677_burnFrom:testSenderNotBurnerReverts() (gas: 13346) +BurnMintERC677_burnFromAlias:testBurnFromSuccess() (gas: 57955) +BurnMintERC677_burnFromAlias:testExceedsBalanceReverts() (gas: 35854) +BurnMintERC677_burnFromAlias:testInsufficientAllowanceReverts() (gas: 21844) +BurnMintERC677_burnFromAlias:testSenderNotBurnerReverts() (gas: 13366) +BurnMintERC677_constructor:testConstructorSuccess() (gas: 1651040) +BurnMintERC677_decreaseApproval:testDecreaseApprovalSuccess() (gas: 31049) +BurnMintERC677_grantMintAndBurnRoles:testGrantMintAndBurnRolesSuccess() (gas: 121279) +BurnMintERC677_grantRole:testGrantBurnAccessSuccess() (gas: 53402) +BurnMintERC677_grantRole:testGrantManySuccess() (gas: 937593) +BurnMintERC677_grantRole:testGrantMintAccessSuccess() (gas: 94280) +BurnMintERC677_increaseApproval:testIncreaseApprovalSuccess() (gas: 44052) +BurnMintERC677_mint:testBasicMintSuccess() (gas: 149664) +BurnMintERC677_mint:testMaxSupplyExceededReverts() (gas: 50323) +BurnMintERC677_mint:testSenderNotMinterReverts() (gas: 11182) +BurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 12455) +BurnMintERC677_transfer:testInvalidAddressReverts() (gas: 10629) +BurnMintERC677_transfer:testTransferSuccess() (gas: 42279) +CallWithExactGas__callWithExactGas:test_CallWithExactGasReceiverErrorSuccess() (gas: 65883) +CallWithExactGas__callWithExactGas:test_CallWithExactGasSafeReturnDataExactGas() (gas: 18293) +CallWithExactGas__callWithExactGas:test_NoContractReverts() (gas: 11544) +CallWithExactGas__callWithExactGas:test_NoGasForCallExactCheckReverts() (gas: 15760) +CallWithExactGas__callWithExactGas:test_NotEnoughGasForCallReverts() (gas: 16210) +CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractExactGasSuccess() (gas: 20033) +CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractReceiverErrorSuccess() (gas: 66394) +CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoContractSuccess() (gas: 12942) +CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoGasForCallExactCheckReturnFalseSuccess() (gas: 12984) +CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NotEnoughGasForCallReturnsFalseSuccess() (gas: 13293) +CallWithExactGas__callWithExactGasSafeReturnData:test_CallWithExactGasSafeReturnDataExactGas() (gas: 20287) +CallWithExactGas__callWithExactGasSafeReturnData:test_NoContractReverts() (gas: 13915) +CallWithExactGas__callWithExactGasSafeReturnData:test_NoGasForCallExactCheckReverts() (gas: 16108) +CallWithExactGas__callWithExactGasSafeReturnData:test_NotEnoughGasForCallReverts() (gas: 16513) +CallWithExactGas__callWithExactGasSafeReturnData:test_callWithExactGasSafeReturnData_ThrowOOGError_Revert() (gas: 36713) +EnumerableMapAddresses_at:testAtSuccess() (gas: 95055) +EnumerableMapAddresses_at:testBytes32AtSuccess() (gas: 94828) +EnumerableMapAddresses_at:testBytesAtSuccess() (gas: 96507) +EnumerableMapAddresses_contains:testBytes32ContainsSuccess() (gas: 93503) +EnumerableMapAddresses_contains:testBytesContainsSuccess() (gas: 93974) +EnumerableMapAddresses_contains:testContainsSuccess() (gas: 93678) +EnumerableMapAddresses_get:testBytes32GetSuccess() (gas: 94238) +EnumerableMapAddresses_get:testBytesGetSuccess() (gas: 95919) +EnumerableMapAddresses_get:testGetSuccess() (gas: 94409) +EnumerableMapAddresses_get_errorMessage:testBytesGetErrorMessageSuccess() (gas: 95852) +EnumerableMapAddresses_get_errorMessage:testGetErrorMessageSuccess() (gas: 94467) +EnumerableMapAddresses_length:testBytes32LengthSuccess() (gas: 72418) +EnumerableMapAddresses_length:testBytesLengthSuccess() (gas: 73035) +EnumerableMapAddresses_length:testLengthSuccess() (gas: 72592) +EnumerableMapAddresses_remove:testBytes32RemoveSuccess() (gas: 73432) +EnumerableMapAddresses_remove:testBytesRemoveSuccess() (gas: 74216) +EnumerableMapAddresses_remove:testRemoveSuccess() (gas: 73651) +EnumerableMapAddresses_set:testBytes32SetSuccess() (gas: 94475) +EnumerableMapAddresses_set:testBytesSetSuccess() (gas: 95405) +EnumerableMapAddresses_set:testSetSuccess() (gas: 94638) +EnumerableMapAddresses_tryGet:testBytes32TryGetSuccess() (gas: 94602) +EnumerableMapAddresses_tryGet:testBytesTryGetSuccess() (gas: 96316) +EnumerableMapAddresses_tryGet:testTryGetSuccess() (gas: 94869) +OpStackBurnMintERC677_constructor:testConstructorSuccess() (gas: 1721342) +OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 291244) +OpStackBurnMintERC677_interfaceCompatibility:testMintCompatibility() (gas: 137917) +OpStackBurnMintERC677_interfaceCompatibility:testStaticFunctionsCompatibility() (gas: 13773) +OpStackBurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 12728) +Ownable2Step_acceptOwnership:test_acceptOwnership_MustBeProposedOwner_reverts() (gas: 10353) +Ownable2Step_acceptOwnership:test_acceptOwnership_success() (gas: 31070) +Ownable2Step_constructor:test_constructor_OwnerCannotBeZero_reverts() (gas: 35924) +Ownable2Step_constructor:test_constructor_success() (gas: 10424) +Ownable2Step_onlyOwner:test_onlyOwner_OnlyCallableByOwner_reverts() (gas: 10746) +Ownable2Step_onlyOwner:test_onlyOwner_success() (gas: 7503) +Ownable2Step_transferOwnership:test_transferOwnership_CannotTransferToSelf_reverts() (gas: 10494) +Ownable2Step_transferOwnership:test_transferOwnership_success() (gas: 30124) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_EmptySubset_Reverts() (gas: 5191) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_EmptySuperset_Reverts() (gas: 4522) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_HasDuplicates_Reverts() (gas: 7738) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_NotASubset_Reverts() (gas: 11700) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SingleElementSubset() (gas: 3908) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SingleElementSubsetAndSuperset_Equal() (gas: 1459) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SingleElementSubsetAndSuperset_NotEqual_Reverts() (gas: 6149) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SubsetEqualsSuperset_NoRevert() (gas: 7830) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SubsetLargerThanSuperset_Reverts() (gas: 15363) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SupersetHasDuplicates_Reverts() (gas: 8767) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_UnsortedSubset_Reverts() (gas: 7106) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_UnsortedSuperset_Reverts() (gas: 8947) +SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_ValidSubset_Success() (gas: 5653) \ No newline at end of file diff --git a/contracts/gas-snapshots/workflow.gas-snapshot b/contracts/gas-snapshots/workflow.gas-snapshot new file mode 100644 index 00000000000..73fdfbf7187 --- /dev/null +++ b/contracts/gas-snapshots/workflow.gas-snapshot @@ -0,0 +1,64 @@ +WorkflowRegistryManager_activateVersion:test_WhenTheVersionNumberIsNotActive_AndWhenThereAreNoActiveVersions() (gas: 528769) +WorkflowRegistryManager_addVersion:test_WhenAutoActivateIsFalse() (gas: 265551) +WorkflowRegistryManager_addVersion:test_WhenAutoActivateIsTrue() (gas: 270596) +WorkflowRegistryManager_getActiveVersion:test_WhenAnActiveVersionExists() (gas: 287760) +WorkflowRegistryManager_getActiveVersion:test_WhenNoActiveVersionIsAvailable() (gas: 13258) +WorkflowRegistryManager_getActiveVersionNumber:test_WhenAnActiveVersionExists() (gas: 283885) +WorkflowRegistryManager_getActiveVersionNumber:test_WhenNoActiveVersionIsAvailable() (gas: 10698) +WorkflowRegistryManager_getAllVersions:test_WhenLimitExceedsMaximumPaginationLimit() (gas: 54503) +WorkflowRegistryManager_getAllVersions:test_WhenRequestingWithInvalidStartIndex() (gas: 11338) +WorkflowRegistryManager_getAllVersions:test_WhenRequestingWithValidStartIndexAndLimitWithinBounds() (gas: 40398) +WorkflowRegistryManager_getLatestVersion:test_WhenNoVersionsHaveBeenRegistered() (gas: 12984) +WorkflowRegistryManager_getLatestVersion:test_WhenVersionsHaveBeenRegistered() (gas: 287791) +WorkflowRegistryManager_getLatestVersionNumber:test_WhenNoVersionsHaveBeenRegistered() (gas: 10637) +WorkflowRegistryManager_getLatestVersionNumber:test_WhenVersionsHaveBeenRegistered() (gas: 284134) +WorkflowRegistryManager_getVersion:test_WhenVersionNumberIsNotRegistered() (gas: 13785) +WorkflowRegistryManager_getVersion:test_WhenVersionNumberIsRegistered() (gas: 288169) +WorkflowRegistryManager_getVersionNumberByContractAddressAndChainID:test_WhenAVersionIsRegisteredForTheContractAddressAndChainIDCombination() (gas: 285022) +WorkflowRegistryManager_getVersionNumberByContractAddressAndChainID:test_WhenNoVersionIsRegisteredForTheContractAddressAndChainIDCombination() (gas: 286634) +WorkflowRegistryManager_getVersionNumberByContractAddressAndChainID:test_WhenTheContractAddressIsInvalid() (gas: 284604) +WorkflowRegistry_activateWorkflow:test_WhenTheCallerIsAnAuthorizedAddress() (gas: 495029) +WorkflowRegistry_deleteWorkflow:test_WhenTheCallerIsAnAuthorizedAddress_AndTheDonIDIsAllowed() (gas: 403945) +WorkflowRegistry_deleteWorkflow:test_WhenTheCallerIsAnAuthorizedAddress_AndTheDonIDIsNotAllowed() (gas: 421748) +WorkflowRegistry_getAllAllowedDONs:test_WhenTheRegistryIsLocked() (gas: 47473) +WorkflowRegistry_getAllAllowedDONs:test_WhenTheSetOfAllowedDONsIsEmpty() (gas: 25780) +WorkflowRegistry_getAllAllowedDONs:test_WhenThereAreMultipleAllowedDONs() (gas: 75437) +WorkflowRegistry_getAllAllowedDONs:test_WhenThereIsASingleAllowedDON() (gas: 16590) +WorkflowRegistry_getAllAuthorizedAddresses:test_WhenTheRegistryIsLocked() (gas: 47740) +WorkflowRegistry_getAllAuthorizedAddresses:test_WhenTheSetOfAuthorizedAddressesIsEmpty() (gas: 26152) +WorkflowRegistry_getAllAuthorizedAddresses:test_WhenThereAreMultipleAuthorizedAddresses() (gas: 78270) +WorkflowRegistry_getAllAuthorizedAddresses:test_WhenThereIsASingleAuthorizedAddress() (gas: 16832) +WorkflowRegistry_getWorkflowMetadata:test_WhenTheRegistryIsLocked() (gas: 519145) +WorkflowRegistry_getWorkflowMetadata:test_WhenTheWorkflowDoesNotExist() (gas: 17543) +WorkflowRegistry_getWorkflowMetadata:test_WhenTheWorkflowExistsWithTheOwnerAndName() (gas: 490001) +WorkflowRegistry_getWorkflowMetadataListByDON:test_WhenLimitExceedsTotalWorkflows() (gas: 128146) +WorkflowRegistry_getWorkflowMetadataListByDON:test_WhenLimitIsEqualToTotalWorkflows() (gas: 128035) +WorkflowRegistry_getWorkflowMetadataListByDON:test_WhenLimitIsLessThanTotalWorkflows() (gas: 90141) +WorkflowRegistry_getWorkflowMetadataListByDON:test_WhenStartIs0() (gas: 128075) +WorkflowRegistry_getWorkflowMetadataListByDON:test_WhenStartIsGreaterThan0() (gas: 90098) +WorkflowRegistry_getWorkflowMetadataListByDON:test_WhenStartIsGreaterThanOrEqualToTotalWorkflows() (gas: 13476) +WorkflowRegistry_getWorkflowMetadataListByDON:test_WhenTheDONHasNoWorkflows() (gas: 13410) +WorkflowRegistry_getWorkflowMetadataListByDON:test_WhenTheRegistryIsLocked() (gas: 158899) +WorkflowRegistry_getWorkflowMetadataListByOwner:test_WhenLimitExceedsTotalWorkflows() (gas: 135174) +WorkflowRegistry_getWorkflowMetadataListByOwner:test_WhenLimitIsEqualToTotalWorkflows() (gas: 135073) +WorkflowRegistry_getWorkflowMetadataListByOwner:test_WhenLimitIsLessThanTotalWorkflows() (gas: 95635) +WorkflowRegistry_getWorkflowMetadataListByOwner:test_WhenStartIs0() (gas: 135113) +WorkflowRegistry_getWorkflowMetadataListByOwner:test_WhenStartIsGreaterThan0() (gas: 95592) +WorkflowRegistry_getWorkflowMetadataListByOwner:test_WhenStartIsGreaterThanOrEqualToTotalWorkflows() (gas: 13764) +WorkflowRegistry_getWorkflowMetadataListByOwner:test_WhenTheOwnerHasNoWorkflows() (gas: 14006) +WorkflowRegistry_getWorkflowMetadataListByOwner:test_WhenTheRegistryIsLocked() (gas: 165968) +WorkflowRegistry_lockRegistry:test_WhenTheCallerIsTheContractOwner() (gas: 38758) +WorkflowRegistry_pauseWorkflow:test_WhenTheDonIDIsAllowed_AndTheCallerIsAnAuthorizedAddress() (gas: 494993) +WorkflowRegistry_pauseWorkflow:test_WhenTheDonIDIsAllowed_AndTheCallerIsAnUnauthorizedAddress() (gas: 502796) +WorkflowRegistry_pauseWorkflow:test_WhenTheDonIDIsNotAllowed_AndTheCallerIsAnAuthorizedAddress() (gas: 502555) +WorkflowRegistry_pauseWorkflow:test_WhenTheDonIDIsNotAllowed_AndTheCallerIsAnUnauthorizedAddress() (gas: 506966) +WorkflowRegistry_registerWorkflow:test_WhenTheWorkflowInputsAreAllValid() (gas: 549769) +WorkflowRegistry_requestForceUpdateSecrets:test_WhenTheCallerIsAnAuthorizedAddress_AndTheWorkflowIsInAnAllowedDON() (gas: 891242) +WorkflowRegistry_requestForceUpdateSecrets:test_WhenTheCallerIsAnAuthorizedAddress_AndTheWorkflowIsNotInAnAllowedDON() (gas: 488397) +WorkflowRegistry_requestForceUpdateSecrets:test_WhenTheCallerIsNotAnAuthorizedAddress() (gas: 486751) +WorkflowRegistry_unlockRegistry:test_WhenTheCallerIsTheContractOwner() (gas: 30325) +WorkflowRegistry_updateAllowedDONs:test_WhenTheBoolInputIsFalse() (gas: 29739) +WorkflowRegistry_updateAllowedDONs:test_WhenTheBoolInputIsTrue() (gas: 170296) +WorkflowRegistry_updateAuthorizedAddresses:test_WhenTheBoolInputIsFalse() (gas: 30278) +WorkflowRegistry_updateAuthorizedAddresses:test_WhenTheBoolInputIsTrue() (gas: 175515) +WorkflowRegistry_updateWorkflow:test_WhenTheWorkflowInputsAreAllValid() (gas: 479601) diff --git a/contracts/src/v0.8/ccip/pools/BurnFromMintTokenPool.sol b/contracts/src/v0.8/ccip/pools/BurnFromMintTokenPool.sol index 1ba13a49745..8ce63a12bb5 100644 --- a/contracts/src/v0.8/ccip/pools/BurnFromMintTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/BurnFromMintTokenPool.sol @@ -18,14 +18,15 @@ import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/tok contract BurnFromMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion { using SafeERC20 for IBurnMintERC20; - string public constant override typeAndVersion = "BurnFromMintTokenPool 1.5.0"; + string public constant override typeAndVersion = "BurnFromMintTokenPool 1.5.1"; constructor( IBurnMintERC20 token, + uint8 localTokenDecimals, address[] memory allowlist, address rmnProxy, address router - ) TokenPool(token, allowlist, rmnProxy, router) { + ) TokenPool(token, localTokenDecimals, allowlist, rmnProxy, router) { // Some tokens allow burning from the sender without approval, but not all do. // To be safe, we approve the pool to burn from the pool. token.safeIncreaseAllowance(address(this), type(uint256).max); diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol index 33026cf0053..30203a4ced7 100644 --- a/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol @@ -14,14 +14,15 @@ import {TokenPool} from "./TokenPool.sol"; /// If that is expected, please make sure the token's burner/minter roles are adjustable. /// @dev This contract is a variant of BurnMintTokenPool that uses `burn(amount)`. contract BurnMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion { - string public constant override typeAndVersion = "BurnMintTokenPool 1.5.0"; + string public constant override typeAndVersion = "BurnMintTokenPool 1.5.1"; constructor( IBurnMintERC20 token, + uint8 localTokenDecimals, address[] memory allowlist, address rmnProxy, address router - ) TokenPool(token, allowlist, rmnProxy, router) {} + ) TokenPool(token, localTokenDecimals, allowlist, rmnProxy, router) {} /// @inheritdoc BurnMintTokenPoolAbstract function _burn( diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol index 6d743ed4a9e..b3bbf4ff5e1 100644 --- a/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPoolAbstract.sol @@ -25,7 +25,10 @@ abstract contract BurnMintTokenPoolAbstract is TokenPool { emit Burned(msg.sender, lockOrBurnIn.amount); - return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); + return Pool.LockOrBurnOutV1({ + destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), + destPoolData: _encodeLocalDecimals() + }); } /// @notice Mint tokens from the pool to the recipient @@ -35,11 +38,15 @@ abstract contract BurnMintTokenPoolAbstract is TokenPool { ) external virtual override returns (Pool.ReleaseOrMintOutV1 memory) { _validateReleaseOrMint(releaseOrMintIn); + // Calculate the local amount + uint256 localAmount = + _calculateLocalAmount(releaseOrMintIn.amount, _parseRemoteDecimals(releaseOrMintIn.sourcePoolData)); + // Mint to the receiver - IBurnMintERC20(address(i_token)).mint(releaseOrMintIn.receiver, releaseOrMintIn.amount); + IBurnMintERC20(address(i_token)).mint(releaseOrMintIn.receiver, localAmount); - emit Minted(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); + emit Minted(msg.sender, releaseOrMintIn.receiver, localAmount); - return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + return Pool.ReleaseOrMintOutV1({destinationAmount: localAmount}); } } diff --git a/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol b/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol index 37541bb8277..fb8538141ca 100644 --- a/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/BurnWithFromMintTokenPool.sol @@ -20,10 +20,11 @@ contract BurnWithFromMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion constructor( IBurnMintERC20 token, + uint8 localTokenDecimals, address[] memory allowlist, address rmnProxy, address router - ) TokenPool(token, allowlist, rmnProxy, router) { + ) TokenPool(token, localTokenDecimals, allowlist, rmnProxy, router) { // Some tokens allow burning from the sender without approval, but not all do. // To be safe, we approve the pool to burn from the pool. token.safeIncreaseAllowance(address(this), type(uint256).max); @@ -37,6 +38,6 @@ contract BurnWithFromMintTokenPool is BurnMintTokenPoolAbstract, ITypeAndVersion } function typeAndVersion() external pure virtual override returns (string memory) { - return "BurnWithFromMintTokenPool 1.5.0"; + return "BurnWithFromMintTokenPool 1.5.1"; } } diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol index 98c20df30c1..ecc28a14dd1 100644 --- a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol @@ -23,7 +23,7 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion event LiquidityTransferred(address indexed from, uint256 amount); - string public constant override typeAndVersion = "LockReleaseTokenPool 1.5.0"; + string public constant override typeAndVersion = "LockReleaseTokenPool 1.5.1"; /// @dev Whether or not the pool accepts liquidity. /// External liquidity is not required when there is one canonical token deployed to a chain, @@ -35,11 +35,12 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion constructor( IERC20 token, + uint8 localTokenDecimals, address[] memory allowlist, address rmnProxy, bool acceptLiquidity, address router - ) TokenPool(token, allowlist, rmnProxy, router) { + ) TokenPool(token, localTokenDecimals, allowlist, rmnProxy, router) { i_acceptLiquidity = acceptLiquidity; } @@ -52,7 +53,10 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion emit Locked(msg.sender, lockOrBurnIn.amount); - return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); + return Pool.LockOrBurnOutV1({ + destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), + destPoolData: _encodeLocalDecimals() + }); } /// @notice Release tokens from the pool to the recipient @@ -62,12 +66,16 @@ contract LockReleaseTokenPool is TokenPool, ILiquidityContainer, ITypeAndVersion ) external virtual override returns (Pool.ReleaseOrMintOutV1 memory) { _validateReleaseOrMint(releaseOrMintIn); + // Calculate the local amount + uint256 localAmount = + _calculateLocalAmount(releaseOrMintIn.amount, _parseRemoteDecimals(releaseOrMintIn.sourcePoolData)); + // Release to the recipient - getToken().safeTransfer(releaseOrMintIn.receiver, releaseOrMintIn.amount); + getToken().safeTransfer(releaseOrMintIn.receiver, localAmount); - emit Released(msg.sender, releaseOrMintIn.receiver, releaseOrMintIn.amount); + emit Released(msg.sender, releaseOrMintIn.receiver, localAmount); - return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); + return Pool.ReleaseOrMintOutV1({destinationAmount: localAmount}); } /// @inheritdoc IERC165 diff --git a/contracts/src/v0.8/ccip/pools/TokenPool.sol b/contracts/src/v0.8/ccip/pools/TokenPool.sol index ac54d93af25..be8cc1ee7a3 100644 --- a/contracts/src/v0.8/ccip/pools/TokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/TokenPool.sol @@ -16,7 +16,21 @@ import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts /// @notice Base abstract class with common functions for all token pools. /// A token pool serves as isolated place for holding tokens and token specific logic /// that may execute as tokens move across the bridge. +/// @dev This pool supports different decimals on different chains but using this feature could impact the total number +/// of tokens in circulation. Since all of the tokens are burned on the source, and a rounded amount is minted on the +/// destination, the number of tokens minted could be less than the number of tokens burned. This is because the source +/// chain does not know about the destination token decimals. This is not a problem if the decimals are the same on both +/// chains. +/// +/// Example: +/// Assume there is a token with 6 decimals on chain A and 3 decimals on chain B. +/// - 1.123456 tokens are burned on chain A. +/// - 1.234 tokens are minted on chain B. +/// When sending the 1.234 tokens back to chain A, you will receive 1.234000 tokens on chain A, effectively losing +/// 0.000456 tokens. In the case of a burnMint pool, these funds are burned. In the case of a lockRelease pool, these +/// funds accumulate in the pool on chain A. abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { + using EnumerableSet for EnumerableSet.Bytes32Set; using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.UintSet; using RateLimiter for RateLimiter.TokenBucket; @@ -32,6 +46,9 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { error InvalidSourcePoolAddress(bytes sourcePoolAddress); error InvalidToken(address token); error Unauthorized(address caller); + error PoolAlreadyAdded(uint64 remoteChainSelector, bytes remotePoolAddress); + error InvalidRemotePoolForChain(uint64 remoteChainSelector, bytes remotePoolAddress); + error InvalidRemoteChainDecimals(bytes sourcePoolData); event Locked(address indexed sender, uint256 amount); event Burned(address indexed sender, uint256 amount); @@ -49,17 +66,17 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { RateLimiter.Config inboundRateLimiterConfig ); event ChainRemoved(uint64 remoteChainSelector); - event RemotePoolSet(uint64 indexed remoteChainSelector, bytes previousPoolAddress, bytes remotePoolAddress); + event RemotePoolAdded(uint64 indexed remoteChainSelector, bytes remotePoolAddress); + event RemotePoolRemoved(uint64 indexed remoteChainSelector, bytes remotePoolAddress); event AllowListAdd(address sender); event AllowListRemove(address sender); event RouterUpdated(address oldRouter, address newRouter); event RateLimitAdminSet(address rateLimitAdmin); struct ChainUpdate { - uint64 remoteChainSelector; // ──╮ Remote chain selector - bool allowed; // ────────────────╯ Whether the chain should be enabled - bytes remotePoolAddress; // Address of the remote pool, ABI encoded in the case of a remote EVM chain. - bytes remoteTokenAddress; // Address of the remote token, ABI encoded in the case of a remote EVM chain. + uint64 remoteChainSelector; // Remote chain selector + bytes[] remotePoolAddresses; // Address of the remote pool, ABI encoded in the case of a remote EVM chain. + bytes remoteTokenAddress; // Address of the remote token, ABI encoded in the case of a remote EVM chain. RateLimiter.Config outboundRateLimiterConfig; // Outbound rate limited config, meaning the rate limits for all of the onRamps for the given chain RateLimiter.Config inboundRateLimiterConfig; // Inbound rate limited config, meaning the rate limits for all of the offRamps for the given chain } @@ -67,20 +84,22 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { struct RemoteChainConfig { RateLimiter.TokenBucket outboundRateLimiterConfig; // Outbound rate limited config, meaning the rate limits for all of the onRamps for the given chain RateLimiter.TokenBucket inboundRateLimiterConfig; // Inbound rate limited config, meaning the rate limits for all of the offRamps for the given chain - bytes remotePoolAddress; // Address of the remote pool, ABI encoded in the case of a remote EVM chain. bytes remoteTokenAddress; // Address of the remote token, ABI encoded in the case of a remote EVM chain. + EnumerableSet.Bytes32Set remotePools; // Set of remote pool hashes, ABI encoded in the case of a remote EVM chain. } - /// @dev The bridgeable token that is managed by this pool. + /// @dev The bridgeable token that is managed by this pool. Pools could support multiple tokens at the same time if + /// required, but this implementation only supports one token. IERC20 internal immutable i_token; + /// @dev The number of decimals of the token managed by this pool. + uint8 internal immutable i_tokenDecimals; /// @dev The address of the RMN proxy address internal immutable i_rmnProxy; /// @dev The immutable flag that indicates if the pool is access-controlled. bool internal immutable i_allowlistEnabled; /// @dev A set of addresses allowed to trigger lockOrBurn as original senders. /// Only takes effect if i_allowlistEnabled is true. - /// This can be used to ensure only token-issuer specified addresses can - /// move tokens. + /// This can be used to ensure only token-issuer specified addresses can move tokens. EnumerableSet.AddressSet internal s_allowlist; /// @dev The address of the router IRouter internal s_router; @@ -89,14 +108,18 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { /// @dev The chain selectors are in uint256 format because of the EnumerableSet implementation. EnumerableSet.UintSet internal s_remoteChainSelectors; mapping(uint64 remoteChainSelector => RemoteChainConfig) internal s_remoteChainConfigs; + /// @notice A mapping of hashed pool addresses to their unhashed form. This is used to be able to find the actually + /// configured pools and not just their hashed versions. + mapping(bytes32 poolAddressHash => bytes poolAddress) internal s_remotePoolAddresses; /// @notice The address of the rate limiter admin. /// @dev Can be address(0) if none is configured. address internal s_rateLimitAdmin; - constructor(IERC20 token, address[] memory allowlist, address rmnProxy, address router) { + constructor(IERC20 token, uint8 localTokenDecimals, address[] memory allowlist, address rmnProxy, address router) { if (address(token) == address(0) || router == address(0) || rmnProxy == address(0)) revert ZeroAddressNotAllowed(); i_token = token; i_rmnProxy = rmnProxy; + i_tokenDecimals = localTokenDecimals; s_router = IRouter(router); // Pool can be set as permissioned or permissionless at deployment time only to save hot-path gas. @@ -106,12 +129,6 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { } } - /// @notice Get RMN proxy address - /// @return rmnProxy Address of RMN proxy - function getRmnProxy() public view returns (address rmnProxy) { - return i_rmnProxy; - } - /// @inheritdoc IPoolV1 function isSupportedToken( address token @@ -125,6 +142,12 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { return i_token; } + /// @notice Get RMN proxy address + /// @return rmnProxy Address of RMN proxy + function getRmnProxy() public view returns (address rmnProxy) { + return i_rmnProxy; + } + /// @notice Gets the pool's Router /// @return router The pool's Router function getRouter() public view returns (address router) { @@ -165,7 +188,7 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { /// @dev This function should always be called before executing a lock or burn. Not doing so would allow /// for various exploits. function _validateLockOrBurn( - Pool.LockOrBurnInV1 memory lockOrBurnIn + Pool.LockOrBurnInV1 calldata lockOrBurnIn ) internal { if (!isSupportedToken(lockOrBurnIn.localToken)) revert InvalidToken(lockOrBurnIn.localToken); if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(lockOrBurnIn.remoteChainSelector)))) revert CursedByRMN(); @@ -185,23 +208,68 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { /// @dev This function should always be called before executing a release or mint. Not doing so would allow /// for various exploits. function _validateReleaseOrMint( - Pool.ReleaseOrMintInV1 memory releaseOrMintIn + Pool.ReleaseOrMintInV1 calldata releaseOrMintIn ) internal { if (!isSupportedToken(releaseOrMintIn.localToken)) revert InvalidToken(releaseOrMintIn.localToken); if (IRMN(i_rmnProxy).isCursed(bytes16(uint128(releaseOrMintIn.remoteChainSelector)))) revert CursedByRMN(); _onlyOffRamp(releaseOrMintIn.remoteChainSelector); // Validates that the source pool address is configured on this pool. - bytes memory configuredRemotePool = getRemotePool(releaseOrMintIn.remoteChainSelector); - if ( - configuredRemotePool.length == 0 - || keccak256(releaseOrMintIn.sourcePoolAddress) != keccak256(configuredRemotePool) - ) { + if (!isRemotePool(releaseOrMintIn.remoteChainSelector, releaseOrMintIn.sourcePoolAddress)) { revert InvalidSourcePoolAddress(releaseOrMintIn.sourcePoolAddress); } + _consumeInboundRateLimit(releaseOrMintIn.remoteChainSelector, releaseOrMintIn.amount); } + // ================================================================ + // │ Token decimals │ + // ================================================================ + + /// @notice Gets the IERC20 token decimals on the local chain. + function getTokenDecimals() public view virtual returns (uint8 decimals) { + return i_tokenDecimals; + } + + function _encodeLocalDecimals() internal view virtual returns (bytes memory) { + return abi.encode(i_tokenDecimals); + } + + function _parseRemoteDecimals( + bytes memory sourcePoolData + ) internal view virtual returns (uint8) { + // Fallback to the local token decimals if the source pool data is empty. This allows for backwards compatibility. + if (sourcePoolData.length == 0) { + return i_tokenDecimals; + } + if (sourcePoolData.length != 32) { + revert InvalidRemoteChainDecimals(sourcePoolData); + } + uint256 remoteDecimals = abi.decode(sourcePoolData, (uint256)); + if (remoteDecimals > type(uint8).max) { + revert InvalidRemoteChainDecimals(sourcePoolData); + } + return uint8(remoteDecimals); + } + + /// @notice Calculates the local amount based on the remote amount and decimals. + /// @param remoteAmount The amount on the remote chain. + /// @param remoteDecimals The decimals of the token on the remote chain. + /// @return The local amount. + /// @dev This function assumes the inputs don't overflow and does no checks to avoid this. For any normal inputs, this + /// should not be a problem. The only way to overflow is when the given arguments cannot be represented in the uint256 + /// type, which means the inputs are invalid. + function _calculateLocalAmount(uint256 remoteAmount, uint8 remoteDecimals) internal view virtual returns (uint256) { + if (remoteDecimals == i_tokenDecimals) { + return remoteAmount; + } + if (remoteDecimals > i_tokenDecimals) { + // Solidity rounds down so there is no risk of minting more tokens than the remote chain sent. + return remoteAmount / (10 ** (remoteDecimals - i_tokenDecimals)); + } + return remoteAmount * (10 ** (i_tokenDecimals - remoteDecimals)); + } + // ================================================================ // │ Chain permissions │ // ================================================================ @@ -209,10 +277,24 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { /// @notice Gets the pool address on the remote chain. /// @param remoteChainSelector Remote chain selector. /// @dev To support non-evm chains, this value is encoded into bytes - function getRemotePool( + function getRemotePools( uint64 remoteChainSelector - ) public view returns (bytes memory) { - return s_remoteChainConfigs[remoteChainSelector].remotePoolAddress; + ) public view returns (bytes[] memory) { + bytes32[] memory remotePoolHashes = s_remoteChainConfigs[remoteChainSelector].remotePools.values(); + + bytes[] memory remotePools = new bytes[](remotePoolHashes.length); + for (uint256 i = 0; i < remotePoolHashes.length; ++i) { + remotePools[i] = s_remotePoolAddresses[remotePoolHashes[i]]; + } + + return remotePools; + } + + /// @notice Checks if the pool address is configured on the remote chain. + /// @param remoteChainSelector Remote chain selector. + /// @param remotePoolAddress The address of the remote pool. + function isRemotePool(uint64 remoteChainSelector, bytes calldata remotePoolAddress) public view returns (bool) { + return s_remoteChainConfigs[remoteChainSelector].remotePools.contains(keccak256(remotePoolAddress)); } /// @notice Gets the token address on the remote chain. @@ -224,16 +306,28 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { return s_remoteChainConfigs[remoteChainSelector].remoteTokenAddress; } - /// @notice Sets the remote pool address for a given chain selector. - /// @param remoteChainSelector The remote chain selector for which the remote pool address is being set. - /// @param remotePoolAddress The address of the remote pool. - function setRemotePool(uint64 remoteChainSelector, bytes calldata remotePoolAddress) external onlyOwner { + /// @notice Adds a remote pool for a given chain selector. This could be due to a pool being upgraded on the remote + /// chain. We don't simply want to replace the old pool as there could still be valid inflight messages from the old + /// pool. This function allows for multiple pools to be added for a single chain selector. + /// @param remoteChainSelector The remote chain selector for which the remote pool address is being added. + /// @param remotePoolAddress The address of the new remote pool. + function addRemotePool(uint64 remoteChainSelector, bytes calldata remotePoolAddress) external onlyOwner { if (!isSupportedChain(remoteChainSelector)) revert NonExistentChain(remoteChainSelector); - bytes memory prevAddress = s_remoteChainConfigs[remoteChainSelector].remotePoolAddress; - s_remoteChainConfigs[remoteChainSelector].remotePoolAddress = remotePoolAddress; + _setRemotePool(remoteChainSelector, remotePoolAddress); + } + + /// @notice Removes the remote pool address for a given chain selector. + /// @dev All inflight txs from the remote pool will be rejected after it is removed. To ensure no loss of funds, there + /// should be no inflight txs from the given pool. + function removeRemotePool(uint64 remoteChainSelector, bytes calldata remotePoolAddress) external onlyOwner { + if (!isSupportedChain(remoteChainSelector)) revert NonExistentChain(remoteChainSelector); + + if (!s_remoteChainConfigs[remoteChainSelector].remotePools.remove(keccak256(remotePoolAddress))) { + revert InvalidRemotePoolForChain(remoteChainSelector, remotePoolAddress); + } - emit RemotePoolSet(remoteChainSelector, prevAddress, remotePoolAddress); + emit RemotePoolRemoved(remoteChainSelector, remotePoolAddress); } /// @inheritdoc IPoolV1 @@ -257,69 +351,120 @@ abstract contract TokenPool is IPoolV1, Ownable2StepMsgSender { /// @notice Sets the permissions for a list of chains selectors. Actual senders for these chains /// need to be allowed on the Router to interact with this pool. - /// @dev Only callable by the owner - /// @param chains A list of chains and their new permission status & rate limits. Rate limits + /// @param remoteChainSelectorsToRemove A list of chain selectors to remove. + /// @param chainsToAdd A list of chains and their new permission status & rate limits. Rate limits /// are only used when the chain is being added through `allowed` being true. + /// @dev Only callable by the owner function applyChainUpdates( - ChainUpdate[] calldata chains + uint64[] calldata remoteChainSelectorsToRemove, + ChainUpdate[] calldata chainsToAdd ) external virtual onlyOwner { - for (uint256 i = 0; i < chains.length; ++i) { - ChainUpdate memory update = chains[i]; - RateLimiter._validateTokenBucketConfig(update.outboundRateLimiterConfig, !update.allowed); - RateLimiter._validateTokenBucketConfig(update.inboundRateLimiterConfig, !update.allowed); - - if (update.allowed) { - // If the chain already exists, revert - if (!s_remoteChainSelectors.add(update.remoteChainSelector)) { - revert ChainAlreadyExists(update.remoteChainSelector); - } - - if (update.remotePoolAddress.length == 0 || update.remoteTokenAddress.length == 0) { - revert ZeroAddressNotAllowed(); - } - - s_remoteChainConfigs[update.remoteChainSelector] = RemoteChainConfig({ - outboundRateLimiterConfig: RateLimiter.TokenBucket({ - rate: update.outboundRateLimiterConfig.rate, - capacity: update.outboundRateLimiterConfig.capacity, - tokens: update.outboundRateLimiterConfig.capacity, - lastUpdated: uint32(block.timestamp), - isEnabled: update.outboundRateLimiterConfig.isEnabled - }), - inboundRateLimiterConfig: RateLimiter.TokenBucket({ - rate: update.inboundRateLimiterConfig.rate, - capacity: update.inboundRateLimiterConfig.capacity, - tokens: update.inboundRateLimiterConfig.capacity, - lastUpdated: uint32(block.timestamp), - isEnabled: update.inboundRateLimiterConfig.isEnabled - }), - remotePoolAddress: update.remotePoolAddress, - remoteTokenAddress: update.remoteTokenAddress - }); - - emit ChainAdded( - update.remoteChainSelector, - update.remoteTokenAddress, - update.outboundRateLimiterConfig, - update.inboundRateLimiterConfig - ); - } else { - // If the chain doesn't exist, revert - if (!s_remoteChainSelectors.remove(update.remoteChainSelector)) { - revert NonExistentChain(update.remoteChainSelector); - } - - delete s_remoteChainConfigs[update.remoteChainSelector]; - - emit ChainRemoved(update.remoteChainSelector); + for (uint256 i = 0; i < remoteChainSelectorsToRemove.length; ++i) { + uint64 remoteChainSelectorToRemove = remoteChainSelectorsToRemove[i]; + // If the chain doesn't exist, revert + if (!s_remoteChainSelectors.remove(remoteChainSelectorToRemove)) { + revert NonExistentChain(remoteChainSelectorToRemove); + } + + // Remove all remote pool hashes for the chain + bytes32[] memory remotePools = s_remoteChainConfigs[remoteChainSelectorToRemove].remotePools.values(); + for (uint256 j = 0; j < remotePools.length; ++j) { + s_remoteChainConfigs[remoteChainSelectorToRemove].remotePools.remove(remotePools[j]); } + + delete s_remoteChainConfigs[remoteChainSelectorToRemove]; + + emit ChainRemoved(remoteChainSelectorToRemove); } + + for (uint256 i = 0; i < chainsToAdd.length; ++i) { + ChainUpdate memory newChain = chainsToAdd[i]; + RateLimiter._validateTokenBucketConfig(newChain.outboundRateLimiterConfig, false); + RateLimiter._validateTokenBucketConfig(newChain.inboundRateLimiterConfig, false); + + if (newChain.remoteTokenAddress.length == 0) { + revert ZeroAddressNotAllowed(); + } + + // If the chain already exists, revert + if (!s_remoteChainSelectors.add(newChain.remoteChainSelector)) { + revert ChainAlreadyExists(newChain.remoteChainSelector); + } + + RemoteChainConfig storage remoteChainConfig = s_remoteChainConfigs[newChain.remoteChainSelector]; + + remoteChainConfig.outboundRateLimiterConfig = RateLimiter.TokenBucket({ + rate: newChain.outboundRateLimiterConfig.rate, + capacity: newChain.outboundRateLimiterConfig.capacity, + tokens: newChain.outboundRateLimiterConfig.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: newChain.outboundRateLimiterConfig.isEnabled + }); + remoteChainConfig.inboundRateLimiterConfig = RateLimiter.TokenBucket({ + rate: newChain.inboundRateLimiterConfig.rate, + capacity: newChain.inboundRateLimiterConfig.capacity, + tokens: newChain.inboundRateLimiterConfig.capacity, + lastUpdated: uint32(block.timestamp), + isEnabled: newChain.inboundRateLimiterConfig.isEnabled + }); + remoteChainConfig.remoteTokenAddress = newChain.remoteTokenAddress; + + for (uint256 j = 0; j < newChain.remotePoolAddresses.length; ++j) { + _setRemotePool(newChain.remoteChainSelector, newChain.remotePoolAddresses[j]); + } + + emit ChainAdded( + newChain.remoteChainSelector, + newChain.remoteTokenAddress, + newChain.outboundRateLimiterConfig, + newChain.inboundRateLimiterConfig + ); + } + } + + /// @notice Adds a pool address to the allowed remote token pools for a particular chain. + /// @param remoteChainSelector The remote chain selector for which the remote pool address is being added. + /// @param remotePoolAddress The address of the new remote pool. + function _setRemotePool(uint64 remoteChainSelector, bytes memory remotePoolAddress) internal { + if (remotePoolAddress.length == 0) { + revert ZeroAddressNotAllowed(); + } + + bytes32 poolHash = keccak256(remotePoolAddress); + + // Check if the pool already exists. + if (!s_remoteChainConfigs[remoteChainSelector].remotePools.add(poolHash)) { + revert PoolAlreadyAdded(remoteChainSelector, remotePoolAddress); + } + + // Add the pool to the mapping to be able to un-hash it later. + s_remotePoolAddresses[poolHash] = remotePoolAddress; + + emit RemotePoolAdded(remoteChainSelector, remotePoolAddress); } // ================================================================ // │ Rate limiting │ // ================================================================ + /// @dev The inbound rate limits should be slightly higher than the outbound rate limits. This is because many chains + /// finalize blocks in batches. CCIP also commits messages in batches: the commit plugin bundles multiple messages in + /// a single merkle root. + /// Imagine the following scenario. + /// - Chain A has an inbound and outbound rate limit of 100 tokens capacity and 1 token per second refill rate. + /// - Chain B has an inbound and outbound rate limit of 100 tokens capacity and 1 token per second refill rate. + /// + /// At time 0: + /// - Chain A sends 100 tokens to Chain B. + /// At time 5: + /// - Chain A sends 5 tokens to Chain B. + /// At time 6: + /// The epoch that contains blocks [0-5] is finalized. + /// Both transactions will be included in the same merkle root and become executable at the same time. This means + /// the token pool on chain B requires a capacity of 105 to successfully execute both messages at the same time. + /// The exact additional capacity required depends on the refill rate and the size of the source chain epochs and the + /// CCIP round time. For simplicity, a 5-10% buffer should be sufficient in most cases. + /// @notice Sets the rate limiter admin address. /// @dev Only callable by the owner. /// @param rateLimitAdmin The new rate limiter admin address. diff --git a/contracts/src/v0.8/ccip/pools/USDC/BurnMintWithLockReleaseFlagTokenPool.sol b/contracts/src/v0.8/ccip/pools/USDC/BurnMintWithLockReleaseFlagTokenPool.sol index fd54387620f..746df9b4e11 100644 --- a/contracts/src/v0.8/ccip/pools/USDC/BurnMintWithLockReleaseFlagTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/USDC/BurnMintWithLockReleaseFlagTokenPool.sol @@ -15,10 +15,11 @@ import {LOCK_RELEASE_FLAG} from "./HybridLockReleaseUSDCTokenPool.sol"; contract BurnMintWithLockReleaseFlagTokenPool is BurnMintTokenPool { constructor( IBurnMintERC20 token, + uint8 localTokenDecimals, address[] memory allowlist, address rmnProxy, address router - ) BurnMintTokenPool(token, allowlist, rmnProxy, router) {} + ) BurnMintTokenPool(token, localTokenDecimals, allowlist, rmnProxy, router) {} /// @notice Burn the token in the pool /// @dev The _validateLockOrBurn check is an essential security check diff --git a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol index addfe06da0b..5998e52f156 100644 --- a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol @@ -50,7 +50,7 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { uint32 sourceDomain; } - string public constant override typeAndVersion = "USDCTokenPool 1.5.0"; + string public constant override typeAndVersion = "USDCTokenPool 1.5.1"; // We restrict to the first version. New pool may be required for subsequent versions. uint32 public constant SUPPORTED_USDC_VERSION = 0; @@ -78,7 +78,7 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { address[] memory allowlist, address rmnProxy, address router - ) TokenPool(token, allowlist, rmnProxy, router) { + ) TokenPool(token, 6, allowlist, rmnProxy, router) { if (address(tokenMessenger) == address(0)) revert InvalidConfig(); IMessageTransmitter transmitter = IMessageTransmitter(tokenMessenger.localMessageTransmitter()); uint32 transmitterVersion = transmitter.version(); @@ -126,7 +126,7 @@ contract USDCTokenPool is TokenPool, ITypeAndVersion { /// @notice Mint tokens from the pool to the recipient /// * sourceTokenData is part of the verified message and passed directly from - /// the offramp so it is guaranteed to be what the lockOrBurn pool released on the + /// the offRamp so it is guaranteed to be what the lockOrBurn pool released on the /// source chain. It contains (nonce, sourceDomain) which is guaranteed by CCTP /// to be unique. /// * offchainTokenData is untrusted (can be supplied by manual execution), but we assert diff --git a/contracts/src/v0.8/ccip/test/BaseTest.t.sol b/contracts/src/v0.8/ccip/test/BaseTest.t.sol index 2770f0fb4d6..dfc9e4e1eb1 100644 --- a/contracts/src/v0.8/ccip/test/BaseTest.t.sol +++ b/contracts/src/v0.8/ccip/test/BaseTest.t.sol @@ -34,6 +34,7 @@ contract BaseTest is Test { uint16 internal constant DEFAULT_TOKEN_FEE_USD_CENTS = 50; uint32 internal constant DEFAULT_TOKEN_DEST_GAS_OVERHEAD = 90_000; uint32 internal constant DEFAULT_TOKEN_BYTES_OVERHEAD = 32; + uint8 internal constant DEFAULT_TOKEN_DECIMALS = 18; bool private s_baseTestInitialized; diff --git a/contracts/src/v0.8/ccip/test/TokenSetup.t.sol b/contracts/src/v0.8/ccip/test/TokenSetup.t.sol index 736f60249ce..db6985c9275 100644 --- a/contracts/src/v0.8/ccip/test/TokenSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/TokenSetup.t.sol @@ -45,8 +45,9 @@ contract TokenSetup is RouterSetup { router = address(s_destRouter); } - LockReleaseTokenPool pool = - new LockReleaseTokenPool(IERC20(token), new address[](0), address(s_mockRMN), true, router); + LockReleaseTokenPool pool = new LockReleaseTokenPool( + IERC20(token), DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), true, router + ); if (isSourcePool) { s_sourcePoolByToken[address(token)] = address(pool); @@ -62,8 +63,9 @@ contract TokenSetup is RouterSetup { router = address(s_destRouter); } - BurnMintTokenPool pool = - new MaybeRevertingBurnMintTokenPool(BurnMintERC20(token), new address[](0), address(s_mockRMN), router); + BurnMintTokenPool pool = new MaybeRevertingBurnMintTokenPool( + BurnMintERC20(token), DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), router + ); BurnMintERC20(token).grantMintAndBurnRoles(address(pool)); if (isSourcePool) { @@ -150,16 +152,18 @@ contract TokenSetup is RouterSetup { tokenAdminRegistry.setPool(token, pool); + bytes[] memory remotePoolAddresses = new bytes[](1); + remotePoolAddresses[0] = abi.encode(remotePoolAddress); + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); chainUpdates[0] = TokenPool.ChainUpdate({ remoteChainSelector: remoteChainSelector, - remotePoolAddress: abi.encode(remotePoolAddress), + remotePoolAddresses: remotePoolAddresses, remoteTokenAddress: abi.encode(remoteToken), - allowed: true, outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); - TokenPool(pool).applyChainUpdates(chainUpdates); + TokenPool(pool).applyChainUpdates(new uint64[](0), chainUpdates); } } diff --git a/contracts/src/v0.8/ccip/test/attacks/OnRamp/OnRampTokenPoolReentrancy.t.sol b/contracts/src/v0.8/ccip/test/attacks/OnRamp/OnRampTokenPoolReentrancy.t.sol index cd3baf1747a..54e08a2a5ef 100644 --- a/contracts/src/v0.8/ccip/test/attacks/OnRamp/OnRampTokenPoolReentrancy.t.sol +++ b/contracts/src/v0.8/ccip/test/attacks/OnRamp/OnRampTokenPoolReentrancy.t.sol @@ -32,16 +32,18 @@ contract OnRampTokenPoolReentrancy is OnRampSetup { address(s_facadeClient), s_sourceToken, address(s_mockRMN), address(s_sourceRouter) ); + bytes[] memory remotePoolAddresses = new bytes[](1); + remotePoolAddresses[0] = abi.encode(s_destPoolBySourceToken[s_sourceTokens[0]]); + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); chainUpdates[0] = TokenPool.ChainUpdate({ remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(s_destPoolBySourceToken[s_sourceTokens[0]]), + remotePoolAddresses: remotePoolAddresses, remoteTokenAddress: abi.encode(s_destTokens[0]), - allowed: true, outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); - s_maliciousTokenPool.applyChainUpdates(chainUpdates); + s_maliciousTokenPool.applyChainUpdates(new uint64[](0), chainUpdates); s_sourcePoolByToken[address(s_sourceToken)] = address(s_maliciousTokenPool); s_tokenAdminRegistry.setPool(address(s_sourceToken), address(s_maliciousTokenPool)); diff --git a/contracts/src/v0.8/ccip/test/attacks/OnRamp/ReentrantMaliciousTokenPool.sol b/contracts/src/v0.8/ccip/test/attacks/OnRamp/ReentrantMaliciousTokenPool.sol index f50f233e737..39ab239e22f 100644 --- a/contracts/src/v0.8/ccip/test/attacks/OnRamp/ReentrantMaliciousTokenPool.sol +++ b/contracts/src/v0.8/ccip/test/attacks/OnRamp/ReentrantMaliciousTokenPool.sol @@ -17,7 +17,7 @@ contract ReentrantMaliciousTokenPool is TokenPool { IERC20 token, address rmnProxy, address router - ) TokenPool(token, new address[](0), rmnProxy, router) { + ) TokenPool(token, 18, new address[](0), rmnProxy, router) { i_facade = facade; } diff --git a/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol b/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol index 77dd57a2d08..282784755dd 100644 --- a/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol +++ b/contracts/src/v0.8/ccip/test/e2e/End2End.t.sol @@ -54,7 +54,9 @@ contract E2E is OnRampSetup, OffRampSetup { for (uint256 i = 0; i < s_sourceTokens.length; ++i) { address token = s_sourceTokens[i]; address pool = address( - new LockReleaseTokenPool(IERC20(token), new address[](0), address(s_mockRMN), true, address(s_sourceRouter2)) + new LockReleaseTokenPool( + IERC20(token), DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), true, address(s_sourceRouter2) + ) ); s_sourcePoolByDestPool[s_destPoolBySourceToken[token]] = pool; diff --git a/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoterSetup.t.sol b/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoterSetup.t.sol index a6551c554e6..92c2b3fe309 100644 --- a/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoterSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/feeQuoter/FeeQuoterSetup.t.sol @@ -362,7 +362,7 @@ contract FeeQuoterFeeSetup is FeeQuoterSetup { return Internal.EVM2AnyTokenTransfer({ sourcePoolAddress: tokenAdminRegistry.getTokenConfig(tokenAmount.token).tokenPool, destTokenAddress: abi.encode(destToken), - extraData: "", + extraData: abi.encode(18), amount: tokenAmount.amount, destExecData: abi.encode(expectedDestGasAmount) }); diff --git a/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol b/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol index 23e13aaa8bb..9def7688147 100644 --- a/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol +++ b/contracts/src/v0.8/ccip/test/helpers/MaybeRevertingBurnMintTokenPool.sol @@ -13,10 +13,11 @@ contract MaybeRevertingBurnMintTokenPool is BurnMintTokenPool { constructor( IBurnMintERC20 token, + uint8 localTokenDecimals, address[] memory allowlist, address rmnProxy, address router - ) BurnMintTokenPool(token, allowlist, rmnProxy, router) {} + ) BurnMintTokenPool(token, localTokenDecimals, allowlist, rmnProxy, router) {} function setShouldRevert( bytes calldata revertReason @@ -52,7 +53,7 @@ contract MaybeRevertingBurnMintTokenPool is BurnMintTokenPool { emit Burned(msg.sender, lockOrBurnIn.amount); return Pool.LockOrBurnOutV1({ destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), - destPoolData: s_sourceTokenData + destPoolData: s_sourceTokenData.length == 0 ? _encodeLocalDecimals() : s_sourceTokenData }); } @@ -68,7 +69,11 @@ contract MaybeRevertingBurnMintTokenPool is BurnMintTokenPool { revert(add(32, revertReason), mload(revertReason)) } } - uint256 amount = releaseOrMintIn.amount * s_releaseOrMintMultiplier; + // Calculate the local amount + uint256 localAmount = + _calculateLocalAmount(releaseOrMintIn.amount, _parseRemoteDecimals(releaseOrMintIn.sourcePoolData)); + + uint256 amount = localAmount * s_releaseOrMintMultiplier; IBurnMintERC20(address(i_token)).mint(releaseOrMintIn.receiver, amount); emit Minted(msg.sender, releaseOrMintIn.receiver, amount); diff --git a/contracts/src/v0.8/ccip/test/helpers/TokenPoolHelper.sol b/contracts/src/v0.8/ccip/test/helpers/TokenPoolHelper.sol index 75f6b1b85df..b323241a62d 100644 --- a/contracts/src/v0.8/ccip/test/helpers/TokenPoolHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/TokenPoolHelper.sol @@ -5,27 +5,53 @@ import {Pool} from "../../libraries/Pool.sol"; import {TokenPool} from "../../pools/TokenPool.sol"; import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; +import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; contract TokenPoolHelper is TokenPool { + using EnumerableSet for EnumerableSet.Bytes32Set; + constructor( IERC20 token, + uint8 localTokenDecimals, address[] memory allowlist, address rmnProxy, address router - ) TokenPool(token, allowlist, rmnProxy, router) {} + ) TokenPool(token, localTokenDecimals, allowlist, rmnProxy, router) {} + + function getRemotePoolHashes() external view returns (bytes32[] memory) { + return new bytes32[](0); // s_remotePoolHashes.values(); + } function lockOrBurn( Pool.LockOrBurnInV1 calldata lockOrBurnIn - ) external view override returns (Pool.LockOrBurnOutV1 memory) { + ) external override returns (Pool.LockOrBurnOutV1 memory) { + _validateLockOrBurn(lockOrBurnIn); + return Pool.LockOrBurnOutV1({destTokenAddress: getRemoteToken(lockOrBurnIn.remoteChainSelector), destPoolData: ""}); } function releaseOrMint( Pool.ReleaseOrMintInV1 calldata releaseOrMintIn - ) external pure override returns (Pool.ReleaseOrMintOutV1 memory) { + ) external override returns (Pool.ReleaseOrMintOutV1 memory) { + _validateReleaseOrMint(releaseOrMintIn); + return Pool.ReleaseOrMintOutV1({destinationAmount: releaseOrMintIn.amount}); } + function encodeLocalDecimals() external view returns (bytes memory) { + return _encodeLocalDecimals(); + } + + function parseRemoteDecimals( + bytes memory sourcePoolData + ) external view returns (uint256) { + return _parseRemoteDecimals(sourcePoolData); + } + + function calculateLocalAmount(uint256 remoteAmount, uint8 remoteDecimals) external view returns (uint256) { + return _calculateLocalAmount(remoteAmount, remoteDecimals); + } + function onlyOnRampModifier( uint64 remoteChainSelector ) external view { diff --git a/contracts/src/v0.8/ccip/test/onRamp/OnRamp/OnRamp.forwardFromRouter.t.sol b/contracts/src/v0.8/ccip/test/onRamp/OnRamp/OnRamp.forwardFromRouter.t.sol index 46726b41c19..7f53f9c5b3c 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/OnRamp/OnRamp.forwardFromRouter.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/OnRamp/OnRamp.forwardFromRouter.t.sol @@ -416,7 +416,11 @@ contract OnRamp_forwardFromRouter is OnRampSetup { vm.startPrank(OWNER); MaybeRevertingBurnMintTokenPool newPool = new MaybeRevertingBurnMintTokenPool( - BurnMintERC20(sourceETH), new address[](0), address(s_mockRMNRemote), address(s_sourceRouter) + BurnMintERC20(sourceETH), + DEFAULT_TOKEN_DECIMALS, + new address[](0), + address(s_mockRMNRemote), + address(s_sourceRouter) ); BurnMintERC20(sourceETH).grantMintAndBurnRoles(address(newPool)); deal(address(sourceETH), address(newPool), type(uint256).max); @@ -425,16 +429,18 @@ contract OnRamp_forwardFromRouter is OnRampSetup { s_tokenAdminRegistry.setPool(sourceETH, address(newPool)); // Allow chain in TokenPool + bytes[] memory remotePoolAddresses = new bytes[](1); + remotePoolAddresses[0] = abi.encode(s_destTokenPool); + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); chainUpdates[0] = TokenPool.ChainUpdate({ remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(s_destTokenPool), + remotePoolAddresses: remotePoolAddresses, remoteTokenAddress: abi.encode(s_destToken), - allowed: true, outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); - newPool.applyChainUpdates(chainUpdates); + newPool.applyChainUpdates(new uint64[](0), chainUpdates); Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(address(sourceETH), 1000); diff --git a/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool/BurnFromMintTokenPool.lockOrBurn.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool/BurnFromMintTokenPool.lockOrBurn.t.sol index 30fb33dae5e..44a8f2299af 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool/BurnFromMintTokenPool.lockOrBurn.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool/BurnFromMintTokenPool.lockOrBurn.t.sol @@ -14,7 +14,7 @@ contract BurnFromMintTokenPool_lockOrBurn is BurnFromMintTokenPoolSetup { assertEq(address(s_mockRMN), s_pool.getRmnProxy()); assertEq(false, s_pool.getAllowListEnabled()); assertEq(type(uint256).max, s_burnMintERC20.allowance(address(s_pool), address(s_pool))); - assertEq("BurnFromMintTokenPool 1.5.0", s_pool.typeAndVersion()); + assertEq("BurnFromMintTokenPool 1.5.1", s_pool.typeAndVersion()); } function test_PoolBurn_Success() public { diff --git a/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool/BurnFromMintTokenPoolSetup.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool/BurnFromMintTokenPoolSetup.t.sol index f4c7674926d..98de04ea3fa 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool/BurnFromMintTokenPoolSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnFromMintTokenPool/BurnFromMintTokenPoolSetup.t.sol @@ -10,7 +10,9 @@ contract BurnFromMintTokenPoolSetup is BurnMintSetup { function setUp() public virtual override { BurnMintSetup.setUp(); - s_pool = new BurnFromMintTokenPool(s_burnMintERC20, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + s_pool = new BurnFromMintTokenPool( + s_burnMintERC20, DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), address(s_sourceRouter) + ); s_burnMintERC20.grantMintAndBurnRoles(address(s_pool)); _applyChainUpdates(address(s_pool)); diff --git a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool/BurnMintSetup.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool/BurnMintSetup.t.sol index b36ab6c5377..6c5d4dd6369 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool/BurnMintSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool/BurnMintSetup.t.sol @@ -24,17 +24,19 @@ contract BurnMintSetup is RouterSetup { function _applyChainUpdates( address pool ) internal { - TokenPool.ChainUpdate[] memory chains = new TokenPool.ChainUpdate[](1); - chains[0] = TokenPool.ChainUpdate({ + bytes[] memory remotePoolAddresses = new bytes[](1); + remotePoolAddresses[0] = abi.encode(s_remoteBurnMintPool); + + TokenPool.ChainUpdate[] memory chainsToAdd = new TokenPool.ChainUpdate[](1); + chainsToAdd[0] = TokenPool.ChainUpdate({ remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(s_remoteBurnMintPool), + remotePoolAddresses: remotePoolAddresses, remoteTokenAddress: abi.encode(s_remoteToken), - allowed: true, outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); - BurnMintTokenPool(pool).applyChainUpdates(chains); + BurnMintTokenPool(pool).applyChainUpdates(new uint64[](0), chainsToAdd); Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_burnMintOnRamp}); diff --git a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool/BurnMintTokenPool.lockOrBurn.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool/BurnMintTokenPool.lockOrBurn.t.sol index 08d27848636..e0bbffa9919 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool/BurnMintTokenPool.lockOrBurn.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool/BurnMintTokenPool.lockOrBurn.t.sol @@ -15,7 +15,9 @@ contract BurnMintTokenPoolSetup is BurnMintSetup { function setUp() public virtual override { BurnMintSetup.setUp(); - s_pool = new BurnMintTokenPool(s_burnMintERC20, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + s_pool = new BurnMintTokenPool( + s_burnMintERC20, DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), address(s_sourceRouter) + ); s_burnMintERC20.grantMintAndBurnRoles(address(s_pool)); _applyChainUpdates(address(s_pool)); @@ -27,7 +29,7 @@ contract BurnMintTokenPool_lockOrBurn is BurnMintTokenPoolSetup { assertEq(address(s_burnMintERC20), address(s_pool.getToken())); assertEq(address(s_mockRMN), s_pool.getRmnProxy()); assertEq(false, s_pool.getAllowListEnabled()); - assertEq("BurnMintTokenPool 1.5.0", s_pool.typeAndVersion()); + assertEq("BurnMintTokenPool 1.5.1", s_pool.typeAndVersion()); } function test_PoolBurn_Success() public { diff --git a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool/BurnMintTokenPool.releaseOrMint.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool/BurnMintTokenPool.releaseOrMint.t.sol index f5151b5bea7..e950b079889 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool/BurnMintTokenPool.releaseOrMint.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnMintTokenPool/BurnMintTokenPool.releaseOrMint.t.sol @@ -14,7 +14,9 @@ contract BurnMintTokenPoolSetup is BurnMintSetup { function setUp() public virtual override { BurnMintSetup.setUp(); - s_pool = new BurnMintTokenPool(s_burnMintERC20, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + s_pool = new BurnMintTokenPool( + s_burnMintERC20, DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), address(s_sourceRouter) + ); s_burnMintERC20.grantMintAndBurnRoles(address(s_pool)); _applyChainUpdates(address(s_pool)); diff --git a/contracts/src/v0.8/ccip/test/pools/BurnMintWithLockReleaseFlagTokenPool/BurnMintWithLockReleaseFlagTokenPool.lockOrBurn.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnMintWithLockReleaseFlagTokenPool/BurnMintWithLockReleaseFlagTokenPool.lockOrBurn.t.sol index b2d991bed09..bb58afd254a 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnMintWithLockReleaseFlagTokenPool/BurnMintWithLockReleaseFlagTokenPool.lockOrBurn.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnMintWithLockReleaseFlagTokenPool/BurnMintWithLockReleaseFlagTokenPool.lockOrBurn.t.sol @@ -18,7 +18,7 @@ contract BurnMintWithLockReleaseFlagTokenPoolSetup is BurnMintSetup { BurnMintSetup.setUp(); s_pool = new BurnMintWithLockReleaseFlagTokenPool( - s_burnMintERC20, new address[](0), address(s_mockRMN), address(s_sourceRouter) + s_burnMintERC20, DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), address(s_sourceRouter) ); s_burnMintERC20.grantMintAndBurnRoles(address(s_pool)); diff --git a/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.lockOrBurn.t.sol b/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.lockOrBurn.t.sol index fd20a567c48..b96dcd78b5d 100644 --- a/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.lockOrBurn.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.lockOrBurn.t.sol @@ -15,8 +15,9 @@ contract BurnWithFromMintTokenPoolSetup is BurnMintSetup { function setUp() public virtual override { BurnMintSetup.setUp(); - s_pool = - new BurnWithFromMintTokenPool(s_burnMintERC20, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + s_pool = new BurnWithFromMintTokenPool( + s_burnMintERC20, DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), address(s_sourceRouter) + ); s_burnMintERC20.grantMintAndBurnRoles(address(s_pool)); _applyChainUpdates(address(s_pool)); @@ -29,7 +30,7 @@ contract BurnWithFromMintTokenPool_lockOrBurn is BurnWithFromMintTokenPoolSetup assertEq(address(s_mockRMN), s_pool.getRmnProxy()); assertEq(false, s_pool.getAllowListEnabled()); assertEq(type(uint256).max, s_burnMintERC20.allowance(address(s_pool), address(s_pool))); - assertEq("BurnWithFromMintTokenPool 1.5.0", s_pool.typeAndVersion()); + assertEq("BurnWithFromMintTokenPool 1.5.1", s_pool.typeAndVersion()); } function test_PoolBurn_Success() public { diff --git a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.canAcceptLiquidity.t.sol b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.canAcceptLiquidity.t.sol index 9a124572f96..63b6e0bc351 100644 --- a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.canAcceptLiquidity.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.canAcceptLiquidity.t.sol @@ -8,8 +8,9 @@ contract LockReleaseTokenPool_canAcceptLiquidity is LockReleaseTokenPoolSetup { function test_CanAcceptLiquidity_Success() public { assertEq(true, s_lockReleaseTokenPool.canAcceptLiquidity()); - s_lockReleaseTokenPool = - new LockReleaseTokenPool(s_token, new address[](0), address(s_mockRMN), false, address(s_sourceRouter)); + s_lockReleaseTokenPool = new LockReleaseTokenPool( + s_token, DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), false, address(s_sourceRouter) + ); assertEq(false, s_lockReleaseTokenPool.canAcceptLiquidity()); } } diff --git a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.provideLiquidity.t.sol b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.provideLiquidity.t.sol index f402750eb19..6ef52e88467 100644 --- a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.provideLiquidity.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.provideLiquidity.t.sol @@ -37,8 +37,9 @@ contract LockReleaseTokenPool_provideLiquidity is LockReleaseTokenPoolSetup { } function test_LiquidityNotAccepted_Revert() public { - s_lockReleaseTokenPool = - new LockReleaseTokenPool(s_token, new address[](0), address(s_mockRMN), false, address(s_sourceRouter)); + s_lockReleaseTokenPool = new LockReleaseTokenPool( + s_token, DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), false, address(s_sourceRouter) + ); vm.expectRevert(LockReleaseTokenPool.LiquidityNotAccepted.selector); s_lockReleaseTokenPool.provideLiquidity(1); diff --git a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.releaseOrMint.t.sol b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.releaseOrMint.t.sol index b20b19fe973..9a67f766448 100644 --- a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.releaseOrMint.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.releaseOrMint.t.sol @@ -10,18 +10,21 @@ import {LockReleaseTokenPoolSetup} from "./LockReleaseTokenPoolSetup.t.sol"; contract LockReleaseTokenPool_releaseOrMint is LockReleaseTokenPoolSetup { function setUp() public virtual override { LockReleaseTokenPoolSetup.setUp(); + + bytes[] memory remotePoolAddresses = new bytes[](1); + remotePoolAddresses[0] = abi.encode(s_sourcePoolAddress); + TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); chainUpdate[0] = TokenPool.ChainUpdate({ remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(s_sourcePoolAddress), + remotePoolAddresses: remotePoolAddresses, remoteTokenAddress: abi.encode(address(2)), - allowed: true, outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); - s_lockReleaseTokenPool.applyChainUpdates(chainUpdate); - s_lockReleaseTokenPoolWithAllowList.applyChainUpdates(chainUpdate); + s_lockReleaseTokenPool.applyChainUpdates(new uint64[](0), chainUpdate); + s_lockReleaseTokenPoolWithAllowList.applyChainUpdates(new uint64[](0), chainUpdate); } function test_ReleaseOrMint_Success() public { @@ -91,19 +94,10 @@ contract LockReleaseTokenPool_releaseOrMint is LockReleaseTokenPoolSetup { } function test_ChainNotAllowed_Revert() public { - address notAllowedRemotePoolAddress = address(1); - - TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); - chainUpdate[0] = TokenPool.ChainUpdate({ - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(notAllowedRemotePoolAddress), - remoteTokenAddress: abi.encode(address(2)), - allowed: false, - outboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}), - inboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}) - }); + uint64[] memory chainsToRemove = new uint64[](1); + chainsToRemove[0] = SOURCE_CHAIN_SELECTOR; - s_lockReleaseTokenPool.applyChainUpdates(chainUpdate); + s_lockReleaseTokenPool.applyChainUpdates(chainsToRemove, new TokenPool.ChainUpdate[](0)); vm.startPrank(s_allowedOffRamp); diff --git a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.transferLiquidity.t.sol b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.transferLiquidity.t.sol index bd2636dbb98..60b9c935bd3 100644 --- a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.transferLiquidity.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPool.transferLiquidity.t.sol @@ -11,8 +11,9 @@ contract LockReleaseTokenPool_transferLiquidity is LockReleaseTokenPoolSetup { function setUp() public virtual override { super.setUp(); - s_oldLockReleaseTokenPool = - new LockReleaseTokenPool(s_token, new address[](0), address(s_mockRMN), true, address(s_sourceRouter)); + s_oldLockReleaseTokenPool = new LockReleaseTokenPool( + s_token, DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), true, address(s_sourceRouter) + ); deal(address(s_token), address(s_oldLockReleaseTokenPool), s_amount); } diff --git a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPoolSetup.t.sol b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPoolSetup.t.sol index 12ffdbe2f46..13bcb8cfdee 100644 --- a/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPoolSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/LockReleaseTokenPool/LockReleaseTokenPoolSetup.t.sol @@ -25,26 +25,30 @@ contract LockReleaseTokenPoolSetup is RouterSetup { RouterSetup.setUp(); s_token = new BurnMintERC20("LINK", "LNK", 18, 0, 0); deal(address(s_token), OWNER, type(uint256).max); - s_lockReleaseTokenPool = - new LockReleaseTokenPool(s_token, new address[](0), address(s_mockRMN), true, address(s_sourceRouter)); + s_lockReleaseTokenPool = new LockReleaseTokenPool( + s_token, DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), true, address(s_sourceRouter) + ); s_allowedList.push(USER_1); s_allowedList.push(OWNER); - s_lockReleaseTokenPoolWithAllowList = - new LockReleaseTokenPool(s_token, s_allowedList, address(s_mockRMN), true, address(s_sourceRouter)); + s_lockReleaseTokenPoolWithAllowList = new LockReleaseTokenPool( + s_token, DEFAULT_TOKEN_DECIMALS, s_allowedList, address(s_mockRMN), true, address(s_sourceRouter) + ); + + bytes[] memory remotePoolAddresses = new bytes[](1); + remotePoolAddresses[0] = abi.encode(s_destPoolAddress); TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); chainUpdate[0] = TokenPool.ChainUpdate({ remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(s_destPoolAddress), + remotePoolAddresses: remotePoolAddresses, remoteTokenAddress: abi.encode(address(2)), - allowed: true, outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); - s_lockReleaseTokenPool.applyChainUpdates(chainUpdate); - s_lockReleaseTokenPoolWithAllowList.applyChainUpdates(chainUpdate); + s_lockReleaseTokenPool.applyChainUpdates(new uint64[](0), chainUpdate); + s_lockReleaseTokenPoolWithAllowList.applyChainUpdates(new uint64[](0), chainUpdate); s_lockReleaseTokenPool.setRebalancer(OWNER); Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.addRemotePool.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.addRemotePool.t.sol new file mode 100644 index 00000000000..dc1ef9d191c --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.addRemotePool.t.sol @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {Pool} from "../../../libraries/Pool.sol"; +import {TokenPool} from "../../../pools/TokenPool.sol"; +import {TokenPoolSetup} from "./TokenPoolSetup.t.sol"; + +contract TokenPool_addRemotePool is TokenPoolSetup { + function test_addRemotePool_Success() public { + // Use a longer data type to ensure it also works for non-evm + bytes memory remotePool = abi.encode(makeAddr("non-evm-1"), makeAddr("non-evm-2")); + + vm.startPrank(OWNER); + + vm.expectEmit(); + emit TokenPool.RemotePoolAdded(DEST_CHAIN_SELECTOR, remotePool); + + s_tokenPool.addRemotePool(DEST_CHAIN_SELECTOR, remotePool); + + bytes[] memory remotePools = s_tokenPool.getRemotePools(DEST_CHAIN_SELECTOR); + + assertEq(remotePools.length, 2); + assertEq(remotePools[0], abi.encode(s_initialRemotePool)); + assertEq(remotePools[1], remotePool); + } + + // function test_addRemotePool_MultipleActive() public { + // bytes[] memory remotePools = new bytes[](3); + // remotePools[0] = abi.encode(makeAddr("remotePool1")); + // remotePools[1] = abi.encode(makeAddr("remotePool2")); + // remotePools[2] = abi.encode(makeAddr("remotePool3")); + // + // address fakeOffRamp = makeAddr("fakeOffRamp"); + // + // vm.mockCall( + // address(s_sourceRouter), abi.encodeCall(Router.isOffRamp, (DEST_CHAIN_SELECTOR, fakeOffRamp)), abi.encode(true) + // ); + // + // vm.startPrank(fakeOffRamp); + // + // vm.expectRevert(abi.encodeWithSelector(TokenPool.InvalidSourcePoolAddress.selector, remotePools[0])); + // s_tokenPool.releaseOrMint(_getReleaseOrMintInV1(remotePools[0])); + // + // // There's already one pool setup through the test setup + // assertEq(s_tokenPool.getRemotePoolHashes().length, 1); + // + // vm.startPrank(OWNER); + // s_tokenPool.addRemotePool(DEST_CHAIN_SELECTOR, remotePools[0]); + // + // vm.startPrank(fakeOffRamp); + // s_tokenPool.releaseOrMint(_getReleaseOrMintInV1(remotePools[0])); + // + // // Adding an additional pool does not remove the previous one + // vm.startPrank(OWNER); + // s_tokenPool.addRemotePool(DEST_CHAIN_SELECTOR, remotePools[1]); + // + // // Both should now work + // assertEq(s_tokenPool.getRemotePoolHashes().length, 3); + // vm.startPrank(fakeOffRamp); + // s_tokenPool.releaseOrMint(_getReleaseOrMintInV1(remotePools[0])); + // s_tokenPool.releaseOrMint(_getReleaseOrMintInV1(remotePools[1])); + // + // // Adding a third pool, and removing the first one + // vm.startPrank(OWNER); + // s_tokenPool.addRemotePool(DEST_CHAIN_SELECTOR, remotePools[2]); + // assertEq(s_tokenPool.getRemotePoolHashes().length, 4); + // s_tokenPool.removeRemotePool(DEST_CHAIN_SELECTOR, remotePools[0]); + // assertEq(s_tokenPool.getRemotePoolHashes().length, 3); + // + // // Only the last two should work + // vm.startPrank(fakeOffRamp); + // vm.expectRevert(abi.encodeWithSelector(TokenPool.InvalidSourcePoolAddress.selector, remotePools[0])); + // s_tokenPool.releaseOrMint(_getReleaseOrMintInV1(remotePools[0])); + // s_tokenPool.releaseOrMint(_getReleaseOrMintInV1(remotePools[1])); + // s_tokenPool.releaseOrMint(_getReleaseOrMintInV1(remotePools[2])); + // + // // Removing the chain removes all associated pool hashes + // vm.startPrank(OWNER); + // + // uint64[] memory chainSelectorsToRemove = new uint64[](1); + // chainSelectorsToRemove[0] = DEST_CHAIN_SELECTOR; + // s_tokenPool.applyChainUpdates(chainSelectorsToRemove, new TokenPool.ChainUpdate[](0)); + // + // assertEq(s_tokenPool.getRemotePoolHashes().length, 0); + // } + + function _getReleaseOrMintInV1( + bytes memory sourcePoolAddress + ) internal view returns (Pool.ReleaseOrMintInV1 memory) { + return Pool.ReleaseOrMintInV1({ + originalSender: abi.encode(OWNER), + remoteChainSelector: DEST_CHAIN_SELECTOR, + receiver: OWNER, + amount: 1000, + localToken: address(s_token), + sourcePoolAddress: sourcePoolAddress, + sourcePoolData: "", + offchainTokenData: "" + }); + } + + // Reverts + + function test_NonExistentChain_Revert() public { + uint64 chainSelector = DEST_CHAIN_SELECTOR + 1; + bytes memory remotePool = abi.encode(type(uint256).max); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, chainSelector)); + + s_tokenPool.addRemotePool(chainSelector, remotePool); + } + + function test_ZeroLengthAddressNotAllowed_Revert() public { + bytes memory remotePool = ""; + + vm.expectRevert(abi.encodeWithSelector(TokenPool.ZeroAddressNotAllowed.selector)); + + s_tokenPool.addRemotePool(DEST_CHAIN_SELECTOR, remotePool); + } + + function test_PoolAlreadyAdded_Revert() public { + uint64 chainSelector = DEST_CHAIN_SELECTOR; + + bytes memory remotePool = abi.encode(type(uint256).max); + + vm.expectEmit(); + emit TokenPool.RemotePoolAdded(chainSelector, remotePool); + + s_tokenPool.addRemotePool(chainSelector, remotePool); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.PoolAlreadyAdded.selector, chainSelector, remotePool)); + + // Attempt to add the same pool again but revert + s_tokenPool.addRemotePool(chainSelector, remotePool); + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.applyAllowListUpdates.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.applyAllowListUpdates.t.sol index 2862b8c71ae..96629445810 100644 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.applyAllowListUpdates.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.applyAllowListUpdates.t.sol @@ -82,7 +82,9 @@ contract TokenPoolWithAllowList_applyAllowListUpdates is TokenPoolWithAllowListS } function test_AllowListNotEnabled_Revert() public { - s_tokenPool = new TokenPoolHelper(s_token, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + s_tokenPool = new TokenPoolHelper( + s_token, DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), address(s_sourceRouter) + ); vm.expectRevert(TokenPool.AllowListNotEnabled.selector); diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.applyChainUpdates.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.applyChainUpdates.t.sol index a24fa3d0e8a..5594a36c31a 100644 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.applyChainUpdates.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.applyChainUpdates.t.sol @@ -2,17 +2,35 @@ pragma solidity 0.8.24; import {Ownable2Step} from "../../../../shared/access/Ownable2Step.sol"; +import {BurnMintERC677} from "../../../../shared/token/ERC677/BurnMintERC677.sol"; import {RateLimiter} from "../../../libraries/RateLimiter.sol"; import {TokenPool} from "../../../pools/TokenPool.sol"; -import {TokenPoolSetup} from "./TokenPoolSetup.t.sol"; -contract TokenPool_applyChainUpdates is TokenPoolSetup { +import {TokenPoolHelper} from "../../helpers/TokenPoolHelper.sol"; +import {RouterSetup} from "../../router/Router/RouterSetup.t.sol"; + +import {IERC20} from "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; + +contract TokenPool_applyChainUpdates is RouterSetup { + IERC20 internal s_token; + TokenPoolHelper internal s_tokenPool; + + function setUp() public virtual override { + RouterSetup.setUp(); + s_token = new BurnMintERC677("LINK", "LNK", 18, 0); + deal(address(s_token), OWNER, type(uint256).max); + + s_tokenPool = new TokenPoolHelper( + s_token, DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), address(s_sourceRouter) + ); + } + function assertState( TokenPool.ChainUpdate[] memory chainUpdates ) public view { uint64[] memory chainSelectors = s_tokenPool.getSupportedChains(); - for (uint256 i = 0; i < chainUpdates.length; i++) { - assertEq(chainUpdates[i].remoteChainSelector, chainSelectors[i]); + for (uint256 i = 0; i < chainUpdates.length; ++i) { + assertEq(chainUpdates[i].remoteChainSelector, chainSelectors[i], "Chain selector mismatch"); } for (uint256 i = 0; i < chainUpdates.length; ++i) { @@ -37,7 +55,7 @@ contract TokenPool_applyChainUpdates is TokenPoolSetup { RateLimiter.Config memory inboundRateLimit2 = RateLimiter.Config({isEnabled: true, capacity: 100e27, rate: 1e17}); // EVM chain, which uses the 160 bit evm address space - uint64 evmChainSelector = 1; + uint64 evmChainSelector = 1789142; bytes memory evmRemotePool = abi.encode(makeAddr("evm_remote_pool")); bytes memory evmRemoteToken = abi.encode(makeAddr("evm_remote_token")); @@ -46,20 +64,24 @@ contract TokenPool_applyChainUpdates is TokenPoolSetup { bytes memory nonEvmRemotePool = abi.encode(keccak256("non_evm_remote_pool")); bytes memory nonEvmRemoteToken = abi.encode(keccak256("non_evm_remote_token")); + bytes[] memory evmRemotePools = new bytes[](1); + evmRemotePools[0] = evmRemotePool; + + bytes[] memory nonEvmRemotePools = new bytes[](1); + nonEvmRemotePools[0] = nonEvmRemotePool; + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); chainUpdates[0] = TokenPool.ChainUpdate({ remoteChainSelector: evmChainSelector, - remotePoolAddress: evmRemotePool, + remotePoolAddresses: evmRemotePools, remoteTokenAddress: evmRemoteToken, - allowed: true, outboundRateLimiterConfig: outboundRateLimit1, inboundRateLimiterConfig: inboundRateLimit1 }); chainUpdates[1] = TokenPool.ChainUpdate({ remoteChainSelector: nonEvmChainSelector, - remotePoolAddress: nonEvmRemotePool, + remotePoolAddresses: nonEvmRemotePools, remoteTokenAddress: nonEvmRemoteToken, - allowed: true, outboundRateLimiterConfig: outboundRateLimit2, inboundRateLimiterConfig: inboundRateLimit2 }); @@ -79,33 +101,28 @@ contract TokenPool_applyChainUpdates is TokenPoolSetup { chainUpdates[1].outboundRateLimiterConfig, chainUpdates[1].inboundRateLimiterConfig ); - s_tokenPool.applyChainUpdates(chainUpdates); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); // on1: rateLimit1, on2: rateLimit2, off1: rateLimit1, off2: rateLimit3 assertState(chainUpdates); // Removing an non-existent chain should revert - TokenPool.ChainUpdate[] memory chainRemoves = new TokenPool.ChainUpdate[](1); uint64 strangerChainSelector = 120938; - chainRemoves[0] = TokenPool.ChainUpdate({ - remoteChainSelector: strangerChainSelector, - remotePoolAddress: evmRemotePool, - remoteTokenAddress: evmRemoteToken, - allowed: false, - outboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}), - inboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}) - }); + + uint64[] memory chainRemoves = new uint64[](1); + chainRemoves[0] = strangerChainSelector; + vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, strangerChainSelector)); - s_tokenPool.applyChainUpdates(chainRemoves); + s_tokenPool.applyChainUpdates(chainRemoves, new TokenPool.ChainUpdate[](0)); // State remains assertState(chainUpdates); // Can remove a chain - chainRemoves[0].remoteChainSelector = evmChainSelector; + chainRemoves[0] = evmChainSelector; vm.expectEmit(); - emit TokenPool.ChainRemoved(chainRemoves[0].remoteChainSelector); + emit TokenPool.ChainRemoved(chainRemoves[0]); - s_tokenPool.applyChainUpdates(chainRemoves); + s_tokenPool.applyChainUpdates(chainRemoves, new TokenPool.ChainUpdate[](0)); // State updated, only chain 2 remains TokenPool.ChainUpdate[] memory singleChainConfigured = new TokenPool.ChainUpdate[](1); @@ -116,94 +133,131 @@ contract TokenPool_applyChainUpdates is TokenPoolSetup { vm.expectRevert( abi.encodeWithSelector(TokenPool.ChainAlreadyExists.selector, singleChainConfigured[0].remoteChainSelector) ); - s_tokenPool.applyChainUpdates(singleChainConfigured); + s_tokenPool.applyChainUpdates(new uint64[](0), singleChainConfigured); } + // function test_applyChainUpdates_UpdatesRemotePoolHashes() public { + // assertEq(s_tokenPool.getRemotePoolHashes().length, 0); + // + // uint64 selector1 = 789; + // uint64 selector2 = 123; + // uint64 selector3 = 456; + // + // bytes memory pool1 = abi.encode(makeAddr("pool1")); + // bytes memory pool2 = abi.encode(makeAddr("pool2")); + // bytes memory pool3 = abi.encode(makeAddr("pool3")); + // + // TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](3); + // chainUpdates[0] = TokenPool.ChainUpdate({ + // remoteChainSelector: selector1, + // remotePoolAddress: pool1, + // remoteTokenAddress: pool1, + // outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + // inboundRateLimiterConfig: _getInboundRateLimiterConfig() + // }); + // chainUpdates[1] = TokenPool.ChainUpdate({ + // remoteChainSelector: selector2, + // remotePoolAddress: pool2, + // remoteTokenAddress: pool2, + // outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + // inboundRateLimiterConfig: _getInboundRateLimiterConfig() + // }); + // chainUpdates[2] = TokenPool.ChainUpdate({ + // remoteChainSelector: selector3, + // remotePoolAddress: pool3, + // remoteTokenAddress: pool3, + // outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + // inboundRateLimiterConfig: _getInboundRateLimiterConfig() + // }); + // + // s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); + // + // assertEq(s_tokenPool.getRemotePoolHashes().length, 3); + // + // // This adds 3 for the first chain, 2 for the second, and 1 for the third for a total of 6. + // // Since each chain already had one, the totals are 4 + 3 + 2 + // for (uint256 i = 0; i < chainUpdates.length; ++i) { + // for (uint256 j = i; j < chainUpdates.length; ++j) { + // s_tokenPool.addRemotePool(chainUpdates[i].remoteChainSelector, abi.encode(i, j)); + // } + // } + // + // assertEq(s_tokenPool.getRemotePoolHashes().length, 4 + 3 + 2); + // + // // Removing a chain should remove all associated pool hashes + // uint64[] memory chainRemoves = new uint64[](1); + // chainRemoves[0] = selector1; + // + // s_tokenPool.applyChainUpdates(chainRemoves, new TokenPool.ChainUpdate[](0)); + // + // assertEq(s_tokenPool.getRemotePoolHashes().length, 3 + 2); + // + // chainRemoves[0] = selector2; + // + // s_tokenPool.applyChainUpdates(chainRemoves, new TokenPool.ChainUpdate[](0)); + // + // assertEq(s_tokenPool.getRemotePoolHashes().length, 2); + // + // chainRemoves[0] = selector3; + // + // s_tokenPool.applyChainUpdates(chainRemoves, new TokenPool.ChainUpdate[](0)); + // + // assertEq(s_tokenPool.getRemotePoolHashes().length, 0); + // } + // Reverts function test_applyChainUpdates_OnlyCallableByOwner_Revert() public { vm.startPrank(STRANGER); vm.expectRevert(Ownable2Step.OnlyCallableByOwner.selector); - s_tokenPool.applyChainUpdates(new TokenPool.ChainUpdate[](0)); + s_tokenPool.applyChainUpdates(new uint64[](0), new TokenPool.ChainUpdate[](0)); } function test_applyChainUpdates_ZeroAddressNotAllowed_Revert() public { + bytes[] memory remotePoolAddresses = new bytes[](1); + remotePoolAddresses[0] = ""; + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); chainUpdates[0] = TokenPool.ChainUpdate({ remoteChainSelector: 1, - remotePoolAddress: "", + remotePoolAddresses: remotePoolAddresses, remoteTokenAddress: abi.encode(address(2)), - allowed: true, outboundRateLimiterConfig: RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e18}), inboundRateLimiterConfig: RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e18}) }); vm.expectRevert(TokenPool.ZeroAddressNotAllowed.selector); - s_tokenPool.applyChainUpdates(chainUpdates); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); chainUpdates = new TokenPool.ChainUpdate[](1); chainUpdates[0] = TokenPool.ChainUpdate({ remoteChainSelector: 1, - remotePoolAddress: abi.encode(address(2)), + remotePoolAddresses: new bytes[](0), remoteTokenAddress: "", - allowed: true, outboundRateLimiterConfig: RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e18}), inboundRateLimiterConfig: RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e18}) }); vm.expectRevert(TokenPool.ZeroAddressNotAllowed.selector); - s_tokenPool.applyChainUpdates(chainUpdates); - } - - function test_applyChainUpdates_DisabledNonZeroRateLimit_Revert() public { - RateLimiter.Config memory outboundRateLimit = RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e18}); - RateLimiter.Config memory inboundRateLimit = RateLimiter.Config({isEnabled: true, capacity: 100e22, rate: 1e12}); - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: 1, - remotePoolAddress: abi.encode(address(1)), - remoteTokenAddress: abi.encode(address(2)), - allowed: true, - outboundRateLimiterConfig: outboundRateLimit, - inboundRateLimiterConfig: inboundRateLimit - }); - - s_tokenPool.applyChainUpdates(chainUpdates); - - chainUpdates[0].allowed = false; - chainUpdates[0].outboundRateLimiterConfig = RateLimiter.Config({isEnabled: false, capacity: 10, rate: 1}); - chainUpdates[0].inboundRateLimiterConfig = RateLimiter.Config({isEnabled: false, capacity: 10, rate: 1}); - - vm.expectRevert( - abi.encodeWithSelector(RateLimiter.DisabledNonZeroRateLimit.selector, chainUpdates[0].outboundRateLimiterConfig) - ); - s_tokenPool.applyChainUpdates(chainUpdates); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); } function test_applyChainUpdates_NonExistentChain_Revert() public { - RateLimiter.Config memory outboundRateLimit = RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}); - RateLimiter.Config memory inboundRateLimit = RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}); - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: 1, - remotePoolAddress: abi.encode(address(1)), - remoteTokenAddress: abi.encode(address(2)), - allowed: false, - outboundRateLimiterConfig: outboundRateLimit, - inboundRateLimiterConfig: inboundRateLimit - }); + uint64[] memory chainRemoves = new uint64[](1); + chainRemoves[0] = 1; - vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, chainUpdates[0].remoteChainSelector)); - s_tokenPool.applyChainUpdates(chainUpdates); + vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, chainRemoves[0])); + s_tokenPool.applyChainUpdates(chainRemoves, new TokenPool.ChainUpdate[](0)); } function test_applyChainUpdates_InvalidRateLimitRate_Revert() public { + uint64 unusedChainSelector = 2 ** 64 - 1; + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: 1, - remotePoolAddress: abi.encode(address(1)), + remoteChainSelector: unusedChainSelector, + remotePoolAddresses: new bytes[](0), remoteTokenAddress: abi.encode(address(2)), - allowed: true, outboundRateLimiterConfig: RateLimiter.Config({isEnabled: true, capacity: 0, rate: 0}), inboundRateLimiterConfig: RateLimiter.Config({isEnabled: true, capacity: 100e22, rate: 1e12}) }); @@ -213,28 +267,28 @@ contract TokenPool_applyChainUpdates is TokenPoolSetup { vm.expectRevert( abi.encodeWithSelector(RateLimiter.InvalidRateLimitRate.selector, chainUpdates[0].outboundRateLimiterConfig) ); - s_tokenPool.applyChainUpdates(chainUpdates); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); chainUpdates[0].outboundRateLimiterConfig.rate = 100; vm.expectRevert( abi.encodeWithSelector(RateLimiter.InvalidRateLimitRate.selector, chainUpdates[0].outboundRateLimiterConfig) ); - s_tokenPool.applyChainUpdates(chainUpdates); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); chainUpdates[0].outboundRateLimiterConfig.capacity = 100; vm.expectRevert( abi.encodeWithSelector(RateLimiter.InvalidRateLimitRate.selector, chainUpdates[0].outboundRateLimiterConfig) ); - s_tokenPool.applyChainUpdates(chainUpdates); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); chainUpdates[0].outboundRateLimiterConfig.capacity = 101; - s_tokenPool.applyChainUpdates(chainUpdates); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); // Change the chain selector as adding the same one would revert - chainUpdates[0].remoteChainSelector = 2; + chainUpdates[0].remoteChainSelector = unusedChainSelector - 1; // Inbound @@ -244,24 +298,24 @@ contract TokenPool_applyChainUpdates is TokenPoolSetup { vm.expectRevert( abi.encodeWithSelector(RateLimiter.InvalidRateLimitRate.selector, chainUpdates[0].inboundRateLimiterConfig) ); - s_tokenPool.applyChainUpdates(chainUpdates); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); chainUpdates[0].inboundRateLimiterConfig.rate = 100; vm.expectRevert( abi.encodeWithSelector(RateLimiter.InvalidRateLimitRate.selector, chainUpdates[0].inboundRateLimiterConfig) ); - s_tokenPool.applyChainUpdates(chainUpdates); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); chainUpdates[0].inboundRateLimiterConfig.capacity = 100; vm.expectRevert( abi.encodeWithSelector(RateLimiter.InvalidRateLimitRate.selector, chainUpdates[0].inboundRateLimiterConfig) ); - s_tokenPool.applyChainUpdates(chainUpdates); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); chainUpdates[0].inboundRateLimiterConfig.capacity = 101; - s_tokenPool.applyChainUpdates(chainUpdates); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); } } diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.calculateLocalAmount.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.calculateLocalAmount.t.sol new file mode 100644 index 00000000000..1b486fa3c8d --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.calculateLocalAmount.t.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {TokenPoolSetup} from "./TokenPoolSetup.t.sol"; + +contract TokenPool_calculateLocalAmount is TokenPoolSetup { + function test_calculateLocalAmount() public view { + uint8 localDecimals = s_tokenPool.getTokenDecimals(); + uint256 remoteAmount = 123e18; + + // Zero decimals should return amount * 10^localDecimals + assertEq(s_tokenPool.calculateLocalAmount(remoteAmount, 0), remoteAmount * 10 ** localDecimals); + + // Equal decimals should return the same amount + assertEq(s_tokenPool.calculateLocalAmount(remoteAmount, localDecimals), remoteAmount); + + // Remote amount with more decimals should return less local amount + uint256 expectedAmount = remoteAmount; + for (uint8 remoteDecimals = localDecimals + 1; remoteDecimals < 36; ++remoteDecimals) { + expectedAmount /= 10; + assertEq(s_tokenPool.calculateLocalAmount(remoteAmount, remoteDecimals), expectedAmount); + } + + // Remote amount with less decimals should return more local amount + expectedAmount = remoteAmount; + for (uint8 remoteDecimals = localDecimals - 1; remoteDecimals > 0; --remoteDecimals) { + expectedAmount *= 10; + assertEq(s_tokenPool.calculateLocalAmount(remoteAmount, remoteDecimals), expectedAmount); + } + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.constructor.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.constructor.t.sol index cfa0d5b9394..6d105ef54ae 100644 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.constructor.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.constructor.t.sol @@ -13,12 +13,15 @@ contract TokenPool_constructor is TokenPoolSetup { assertEq(address(s_mockRMN), s_tokenPool.getRmnProxy()); assertEq(false, s_tokenPool.getAllowListEnabled()); assertEq(address(s_sourceRouter), s_tokenPool.getRouter()); + assertEq(DEFAULT_TOKEN_DECIMALS, s_tokenPool.getTokenDecimals()); } // Reverts function test_ZeroAddressNotAllowed_Revert() public { vm.expectRevert(TokenPool.ZeroAddressNotAllowed.selector); - s_tokenPool = new TokenPoolHelper(IERC20(address(0)), new address[](0), address(s_mockRMN), address(s_sourceRouter)); + s_tokenPool = new TokenPoolHelper( + IERC20(address(0)), DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), address(s_sourceRouter) + ); } } diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.getRemotePool.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.getRemotePool.t.sol index a3acd8f2690..5e619aede4c 100644 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.getRemotePool.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.getRemotePool.t.sol @@ -5,25 +5,29 @@ import {TokenPool} from "../../../pools/TokenPool.sol"; import {TokenPoolSetup} from "./TokenPoolSetup.t.sol"; contract TokenPool_getRemotePool is TokenPoolSetup { - function test_getRemotePool_Success() public { - uint64 chainSelector = 123124; - address remotePool = makeAddr("remotePool"); - address remoteToken = makeAddr("remoteToken"); + function test_getRemotePools() public { + uint64 chainSelector = DEST_CHAIN_SELECTOR + 1; + bytes memory remotePool = abi.encode(makeAddr("remotePool")); + bytes memory remoteToken = abi.encode(makeAddr("remoteToken")); // Zero indicates nothing is set - assertEq(0, s_tokenPool.getRemotePool(chainSelector).length); + assertEq(0, s_tokenPool.getRemotePools(chainSelector).length); + + bytes[] memory remotePoolAddresses = new bytes[](1); + remotePoolAddresses[0] = remotePool; TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); chainUpdates[0] = TokenPool.ChainUpdate({ remoteChainSelector: chainSelector, - remotePoolAddress: abi.encode(remotePool), - remoteTokenAddress: abi.encode(remoteToken), - allowed: true, + remotePoolAddresses: remotePoolAddresses, + remoteTokenAddress: remoteToken, outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); - s_tokenPool.applyChainUpdates(chainUpdates); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdates); - assertEq(remotePool, abi.decode(s_tokenPool.getRemotePool(chainSelector), (address))); + bytes[] memory remotePools = s_tokenPool.getRemotePools(chainSelector); + assertEq(1, remotePools.length); + assertEq(remotePool, remotePools[0]); } } diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.onlyOffRamp.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.onlyOffRamp.t.sol index c514b343d62..8df07a285f3 100644 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.onlyOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.onlyOffRamp.t.sol @@ -2,26 +2,14 @@ pragma solidity 0.8.24; import {Router} from "../../../Router.sol"; -import {RateLimiter} from "../../../libraries/RateLimiter.sol"; import {TokenPool} from "../../../pools/TokenPool.sol"; import {TokenPoolSetup} from "./TokenPoolSetup.t.sol"; contract TokenPool_onlyOffRamp is TokenPoolSetup { function test_onlyOffRamp_Success() public { - uint64 chainSelector = 13377; + uint64 chainSelector = DEST_CHAIN_SELECTOR; address offRamp = makeAddr("onRamp"); - TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); - chainUpdate[0] = TokenPool.ChainUpdate({ - remoteChainSelector: chainSelector, - remotePoolAddress: abi.encode(address(1)), - remoteTokenAddress: abi.encode(address(2)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - s_tokenPool.applyChainUpdates(chainUpdate); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); offRampUpdates[0] = Router.OffRamp({sourceChainSelector: chainSelector, offRamp: offRamp}); s_sourceRouter.applyRampUpdates(new Router.OnRamp[](0), new Router.OffRamp[](0), offRampUpdates); @@ -32,7 +20,7 @@ contract TokenPool_onlyOffRamp is TokenPoolSetup { } function test_ChainNotAllowed_Revert() public { - uint64 chainSelector = 13377; + uint64 chainSelector = DEST_CHAIN_SELECTOR + 1; address offRamp = makeAddr("onRamp"); vm.startPrank(offRamp); @@ -45,13 +33,12 @@ contract TokenPool_onlyOffRamp is TokenPoolSetup { TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); chainUpdate[0] = TokenPool.ChainUpdate({ remoteChainSelector: chainSelector, - remotePoolAddress: abi.encode(address(1)), + remotePoolAddresses: new bytes[](0), remoteTokenAddress: abi.encode(address(2)), - allowed: true, outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); - s_tokenPool.applyChainUpdates(chainUpdate); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdate); Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); offRampUpdates[0] = Router.OffRamp({sourceChainSelector: chainSelector, offRamp: offRamp}); @@ -61,17 +48,11 @@ contract TokenPool_onlyOffRamp is TokenPoolSetup { // Should succeed now that we've added the chain s_tokenPool.onlyOffRampModifier(chainSelector); - chainUpdate[0] = TokenPool.ChainUpdate({ - remoteChainSelector: chainSelector, - remotePoolAddress: abi.encode(address(1)), - remoteTokenAddress: abi.encode(address(2)), - allowed: false, - outboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}), - inboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}) - }); + uint64[] memory chainsToRemove = new uint64[](1); + chainsToRemove[0] = chainSelector; vm.startPrank(OWNER); - s_tokenPool.applyChainUpdates(chainUpdate); + s_tokenPool.applyChainUpdates(chainsToRemove, new TokenPool.ChainUpdate[](0)); vm.startPrank(offRamp); @@ -80,20 +61,9 @@ contract TokenPool_onlyOffRamp is TokenPoolSetup { } function test_CallerIsNotARampOnRouter_Revert() public { - uint64 chainSelector = 13377; + uint64 chainSelector = DEST_CHAIN_SELECTOR; address offRamp = makeAddr("offRamp"); - TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); - chainUpdate[0] = TokenPool.ChainUpdate({ - remoteChainSelector: chainSelector, - remotePoolAddress: abi.encode(address(1)), - remoteTokenAddress: abi.encode(address(2)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - s_tokenPool.applyChainUpdates(chainUpdate); - vm.startPrank(offRamp); vm.expectRevert(abi.encodeWithSelector(TokenPool.CallerIsNotARampOnRouter.selector, offRamp)); diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.onlyOnRamp.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.onlyOnRamp.t.sol index 5e3e6e31c12..be0c21e4c1e 100644 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.onlyOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.onlyOnRamp.t.sol @@ -2,26 +2,14 @@ pragma solidity 0.8.24; import {Router} from "../../../Router.sol"; -import {RateLimiter} from "../../../libraries/RateLimiter.sol"; import {TokenPool} from "../../../pools/TokenPool.sol"; import {TokenPoolSetup} from "./TokenPoolSetup.t.sol"; contract TokenPool_onlyOnRamp is TokenPoolSetup { function test_onlyOnRamp_Success() public { - uint64 chainSelector = 13377; + uint64 chainSelector = DEST_CHAIN_SELECTOR; address onRamp = makeAddr("onRamp"); - TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); - chainUpdate[0] = TokenPool.ChainUpdate({ - remoteChainSelector: chainSelector, - remotePoolAddress: abi.encode(address(1)), - remoteTokenAddress: abi.encode(address(2)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - s_tokenPool.applyChainUpdates(chainUpdate); - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); onRampUpdates[0] = Router.OnRamp({destChainSelector: chainSelector, onRamp: onRamp}); s_sourceRouter.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), new Router.OffRamp[](0)); @@ -32,7 +20,7 @@ contract TokenPool_onlyOnRamp is TokenPoolSetup { } function test_ChainNotAllowed_Revert() public { - uint64 chainSelector = 13377; + uint64 chainSelector = DEST_CHAIN_SELECTOR + 1; address onRamp = makeAddr("onRamp"); vm.startPrank(onRamp); @@ -45,13 +33,12 @@ contract TokenPool_onlyOnRamp is TokenPoolSetup { TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); chainUpdate[0] = TokenPool.ChainUpdate({ remoteChainSelector: chainSelector, - remotePoolAddress: abi.encode(address(1)), + remotePoolAddresses: new bytes[](0), remoteTokenAddress: abi.encode(address(2)), - allowed: true, outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); - s_tokenPool.applyChainUpdates(chainUpdate); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdate); Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); onRampUpdates[0] = Router.OnRamp({destChainSelector: chainSelector, onRamp: onRamp}); @@ -61,17 +48,11 @@ contract TokenPool_onlyOnRamp is TokenPoolSetup { // Should succeed now that we've added the chain s_tokenPool.onlyOnRampModifier(chainSelector); - chainUpdate[0] = TokenPool.ChainUpdate({ - remoteChainSelector: chainSelector, - remotePoolAddress: abi.encode(address(1)), - remoteTokenAddress: abi.encode(address(2)), - allowed: false, - outboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}), - inboundRateLimiterConfig: RateLimiter.Config({isEnabled: false, capacity: 0, rate: 0}) - }); + uint64[] memory chainsToRemove = new uint64[](1); + chainsToRemove[0] = chainSelector; vm.startPrank(OWNER); - s_tokenPool.applyChainUpdates(chainUpdate); + s_tokenPool.applyChainUpdates(chainsToRemove, new TokenPool.ChainUpdate[](0)); vm.startPrank(onRamp); @@ -80,20 +61,9 @@ contract TokenPool_onlyOnRamp is TokenPoolSetup { } function test_CallerIsNotARampOnRouter_Revert() public { - uint64 chainSelector = 13377; + uint64 chainSelector = DEST_CHAIN_SELECTOR; address onRamp = makeAddr("onRamp"); - TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); - chainUpdate[0] = TokenPool.ChainUpdate({ - remoteChainSelector: chainSelector, - remotePoolAddress: abi.encode(address(1)), - remoteTokenAddress: abi.encode(address(2)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - s_tokenPool.applyChainUpdates(chainUpdate); - vm.startPrank(onRamp); vm.expectRevert(abi.encodeWithSelector(TokenPool.CallerIsNotARampOnRouter.selector, onRamp)); diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.parseRemoteDecimals.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.parseRemoteDecimals.t.sol new file mode 100644 index 00000000000..9817fe227e4 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.parseRemoteDecimals.t.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {TokenPool} from "../../../pools/TokenPool.sol"; +import {TokenPoolSetup} from "./TokenPoolSetup.t.sol"; + +contract TokenPool_parseRemoteDecimals is TokenPoolSetup { + function test_parseRemoteDecimals() public view { + uint256 remoteDecimals = 12; + bytes memory encodedDecimals = abi.encode(remoteDecimals); + + assertEq(s_tokenPool.parseRemoteDecimals(encodedDecimals), remoteDecimals); + + assertEq(s_tokenPool.parseRemoteDecimals(s_tokenPool.encodeLocalDecimals()), s_tokenPool.getTokenDecimals()); + } + + function test_parseRemoteDecimals_NoDecimalsDefaultsToLocalDecimals() public view { + assertEq(s_tokenPool.parseRemoteDecimals(""), s_tokenPool.getTokenDecimals()); + } + + function test_parseRemoteDecimals_RevertWhen_InvalidRemoteChainDecimals_DigitTooLarge() public { + bytes memory encodedDecimals = abi.encode(uint256(256)); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.InvalidRemoteChainDecimals.selector, encodedDecimals)); + + s_tokenPool.parseRemoteDecimals(encodedDecimals); + } + + function test_parseRemoteDecimals_RevertWhen_InvalidRemoteChainDecimals_WrongType() public { + bytes memory encodedDecimals = abi.encode(uint256(256), "wrong type"); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.InvalidRemoteChainDecimals.selector, encodedDecimals)); + + s_tokenPool.parseRemoteDecimals(encodedDecimals); + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.removeRemotePool.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.removeRemotePool.t.sol new file mode 100644 index 00000000000..2fa9ef16624 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.removeRemotePool.t.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {TokenPool} from "../../../pools/TokenPool.sol"; +import {TokenPoolSetup} from "./TokenPoolSetup.t.sol"; + +contract TokenPool_removeRemotePool is TokenPoolSetup { + function test_removeRemotePool_Success() public { + uint64 chainSelector = DEST_CHAIN_SELECTOR; + // Use a longer data type to ensure it also works for non-evm + bytes memory remotePool = abi.encode(makeAddr("non-evm-1"), makeAddr("non-evm-2")); + + vm.expectEmit(); + emit TokenPool.RemotePoolAdded(chainSelector, remotePool); + + // Add the remote pool properly so that it can be removed + s_tokenPool.addRemotePool(chainSelector, remotePool); + + bytes[] memory remotePools = s_tokenPool.getRemotePools(chainSelector); + assertEq(remotePools.length, 2); + assertEq(remotePools[0], abi.encode(s_initialRemotePool)); + assertEq(remotePools[1], remotePool); + + vm.expectEmit(); + emit TokenPool.RemotePoolRemoved(chainSelector, remotePool); + + s_tokenPool.removeRemotePool(chainSelector, remotePool); + + remotePools = s_tokenPool.getRemotePools(chainSelector); + assertEq(remotePools.length, 1); + assertEq(remotePools[0], abi.encode(s_initialRemotePool)); + + // Assert that it can be added after it has been removed + s_tokenPool.addRemotePool(chainSelector, remotePool); + + remotePools = s_tokenPool.getRemotePools(chainSelector); + assertEq(remotePools.length, 2); + assertEq(remotePools[0], abi.encode(s_initialRemotePool)); + assertEq(remotePools[1], remotePool); + } + + // Reverts + + function test_NonExistentChain_Revert() public { + uint64 chainSelector = DEST_CHAIN_SELECTOR + 1; + bytes memory remotePool = abi.encode(type(uint256).max); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, chainSelector)); + + s_tokenPool.removeRemotePool(chainSelector, remotePool); + } + + function test_InvalidRemotePoolForChain_Revert() public { + uint64 chainSelector = DEST_CHAIN_SELECTOR; + bytes memory remotePool = abi.encode(type(uint256).max); + + vm.expectRevert(abi.encodeWithSelector(TokenPool.InvalidRemotePoolForChain.selector, chainSelector, remotePool)); + + s_tokenPool.removeRemotePool(chainSelector, remotePool); + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setChainRateLimiterConfig.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setChainRateLimiterConfig.t.sol index e44dc96f1a8..4dea9bf4032 100644 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setChainRateLimiterConfig.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setChainRateLimiterConfig.t.sol @@ -6,23 +6,6 @@ import {TokenPool} from "../../../pools/TokenPool.sol"; import {TokenPoolSetup} from "./TokenPoolSetup.t.sol"; contract TokenPool_setChainRateLimiterConfig is TokenPoolSetup { - uint64 internal s_remoteChainSelector; - - function setUp() public virtual override { - TokenPoolSetup.setUp(); - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); - s_remoteChainSelector = 123124; - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: s_remoteChainSelector, - remotePoolAddress: abi.encode(address(2)), - remoteTokenAddress: abi.encode(address(3)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - s_tokenPool.applyChainUpdates(chainUpdates); - } - function testFuzz_SetChainRateLimiterConfig_Success(uint128 capacity, uint128 rate, uint32 newTime) public { // Cap the lower bound to 4 so 4/2 is still >= 2 vm.assume(capacity >= 4); @@ -32,8 +15,8 @@ contract TokenPool_setChainRateLimiterConfig is TokenPoolSetup { newTime = uint32(bound(newTime, block.timestamp + 1, type(uint32).max)); vm.warp(newTime); - uint256 oldOutboundTokens = s_tokenPool.getCurrentOutboundRateLimiterState(s_remoteChainSelector).tokens; - uint256 oldInboundTokens = s_tokenPool.getCurrentInboundRateLimiterState(s_remoteChainSelector).tokens; + uint256 oldOutboundTokens = s_tokenPool.getCurrentOutboundRateLimiterState(DEST_CHAIN_SELECTOR).tokens; + uint256 oldInboundTokens = s_tokenPool.getCurrentInboundRateLimiterState(DEST_CHAIN_SELECTOR).tokens; RateLimiter.Config memory newOutboundConfig = RateLimiter.Config({isEnabled: true, capacity: capacity, rate: rate}); RateLimiter.Config memory newInboundConfig = @@ -44,13 +27,13 @@ contract TokenPool_setChainRateLimiterConfig is TokenPoolSetup { vm.expectEmit(); emit RateLimiter.ConfigChanged(newInboundConfig); vm.expectEmit(); - emit TokenPool.ChainConfigured(s_remoteChainSelector, newOutboundConfig, newInboundConfig); + emit TokenPool.ChainConfigured(DEST_CHAIN_SELECTOR, newOutboundConfig, newInboundConfig); - s_tokenPool.setChainRateLimiterConfig(s_remoteChainSelector, newOutboundConfig, newInboundConfig); + s_tokenPool.setChainRateLimiterConfig(DEST_CHAIN_SELECTOR, newOutboundConfig, newInboundConfig); uint256 expectedTokens = RateLimiter._min(newOutboundConfig.capacity, oldOutboundTokens); - RateLimiter.TokenBucket memory bucket = s_tokenPool.getCurrentOutboundRateLimiterState(s_remoteChainSelector); + RateLimiter.TokenBucket memory bucket = s_tokenPool.getCurrentOutboundRateLimiterState(DEST_CHAIN_SELECTOR); assertEq(bucket.capacity, newOutboundConfig.capacity); assertEq(bucket.rate, newOutboundConfig.rate); assertEq(bucket.tokens, expectedTokens); @@ -58,7 +41,7 @@ contract TokenPool_setChainRateLimiterConfig is TokenPoolSetup { expectedTokens = RateLimiter._min(newInboundConfig.capacity, oldInboundTokens); - bucket = s_tokenPool.getCurrentInboundRateLimiterState(s_remoteChainSelector); + bucket = s_tokenPool.getCurrentInboundRateLimiterState(DEST_CHAIN_SELECTOR); assertEq(bucket.capacity, newInboundConfig.capacity); assertEq(bucket.rate, newInboundConfig.rate); assertEq(bucket.tokens, expectedTokens); @@ -72,7 +55,7 @@ contract TokenPool_setChainRateLimiterConfig is TokenPoolSetup { vm.expectRevert(abi.encodeWithSelector(TokenPool.Unauthorized.selector, STRANGER)); s_tokenPool.setChainRateLimiterConfig( - s_remoteChainSelector, _getOutboundRateLimiterConfig(), _getInboundRateLimiterConfig() + DEST_CHAIN_SELECTOR, _getOutboundRateLimiterConfig(), _getInboundRateLimiterConfig() ); } diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setRemotePool.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setRemotePool.t.sol deleted file mode 100644 index d305e131793..00000000000 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setRemotePool.t.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.24; - -import {Ownable2Step} from "../../../../shared/access/Ownable2Step.sol"; -import {TokenPool} from "../../../pools/TokenPool.sol"; -import {TokenPoolSetup} from "./TokenPoolSetup.t.sol"; - -contract TokenPool_setRemotePool is TokenPoolSetup { - function test_setRemotePool_Success() public { - uint64 chainSelector = DEST_CHAIN_SELECTOR; - address initialPool = makeAddr("remotePool"); - address remoteToken = makeAddr("remoteToken"); - // The new pool is a non-evm pool, as it doesn't fit in the normal 160 bits - bytes memory newPool = abi.encode(type(uint256).max); - - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: chainSelector, - remotePoolAddress: abi.encode(initialPool), - remoteTokenAddress: abi.encode(remoteToken), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - s_tokenPool.applyChainUpdates(chainUpdates); - - vm.expectEmit(); - emit TokenPool.RemotePoolSet(chainSelector, abi.encode(initialPool), newPool); - - s_tokenPool.setRemotePool(chainSelector, newPool); - - assertEq(keccak256(newPool), keccak256(s_tokenPool.getRemotePool(chainSelector))); - } - - // Reverts - - function test_setRemotePool_NonExistentChain_Reverts() public { - uint64 chainSelector = 123124; - bytes memory remotePool = abi.encode(makeAddr("remotePool")); - - vm.expectRevert(abi.encodeWithSelector(TokenPool.NonExistentChain.selector, chainSelector)); - s_tokenPool.setRemotePool(chainSelector, remotePool); - } - - function test_setRemotePool_OnlyOwner_Reverts() public { - vm.startPrank(STRANGER); - - vm.expectRevert(Ownable2Step.OnlyCallableByOwner.selector); - s_tokenPool.setRemotePool(123124, abi.encode(makeAddr("remotePool"))); - } -} diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setRouter.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setRouter.t.sol index 288b7f7081d..4bf85f3af9f 100644 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setRouter.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPool.setRouter.t.sol @@ -17,4 +17,14 @@ contract TokenPoolWithAllowList_setRouter is TokenPoolWithAllowListSetup { assertEq(newRouter, s_tokenPool.getRouter()); } + + // Reverts + + function test_ZeroAddressNotAllowed_Revert() public { + address newRouter = address(0); + + vm.expectRevert(TokenPool.ZeroAddressNotAllowed.selector); + + s_tokenPool.setRouter(newRouter); + } } diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPoolSetup.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPoolSetup.t.sol index 4e81c1c534a..b2bdeefee12 100644 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPoolSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPoolSetup.t.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.24; import {BurnMintERC20} from "../../../../shared/token/ERC20/BurnMintERC20.sol"; +import {TokenPool} from "../../../pools/TokenPool.sol"; import {TokenPoolHelper} from "../../helpers/TokenPoolHelper.sol"; import {RouterSetup} from "../../router/Router/RouterSetup.t.sol"; @@ -11,11 +12,29 @@ contract TokenPoolSetup is RouterSetup { IERC20 internal s_token; TokenPoolHelper internal s_tokenPool; + address internal s_initialRemotePool = makeAddr("initialRemotePool"); + address internal s_initialRemoteToken = makeAddr("initialRemoteToken"); + function setUp() public virtual override { RouterSetup.setUp(); s_token = new BurnMintERC20("LINK", "LNK", 18, 0, 0); deal(address(s_token), OWNER, type(uint256).max); - s_tokenPool = new TokenPoolHelper(s_token, new address[](0), address(s_mockRMN), address(s_sourceRouter)); + s_tokenPool = new TokenPoolHelper( + s_token, DEFAULT_TOKEN_DECIMALS, new address[](0), address(s_mockRMN), address(s_sourceRouter) + ); + + bytes[] memory remotePoolAddresses = new bytes[](1); + remotePoolAddresses[0] = abi.encode(s_initialRemotePool); + + TokenPool.ChainUpdate[] memory chainUpdate = new TokenPool.ChainUpdate[](1); + chainUpdate[0] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddresses: remotePoolAddresses, + remoteTokenAddress: abi.encode(s_initialRemoteToken), + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() + }); + s_tokenPool.applyChainUpdates(new uint64[](0), chainUpdate); } } diff --git a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPoolWithAllowListSetup.t.sol b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPoolWithAllowListSetup.t.sol index d441c11c352..478e8996376 100644 --- a/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPoolWithAllowListSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/TokenPool/TokenPoolWithAllowListSetup.t.sol @@ -13,6 +13,8 @@ contract TokenPoolWithAllowListSetup is TokenPoolSetup { s_allowedSenders.push(STRANGER); s_allowedSenders.push(OWNER); - s_tokenPool = new TokenPoolHelper(s_token, s_allowedSenders, address(s_mockRMN), address(s_sourceRouter)); + s_tokenPool = new TokenPoolHelper( + s_token, DEFAULT_TOKEN_DECIMALS, s_allowedSenders, address(s_mockRMN), address(s_sourceRouter) + ); } } diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.lockOrBurn.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.lockOrBurn.t.sol index 0cceb42ad6d..394357f213f 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.lockOrBurn.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.lockOrBurn.t.sol @@ -1,142 +1,16 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IBurnMintERC20} from "../../../../../shared/token/ERC20/IBurnMintERC20.sol"; import {ITokenMessenger} from "../../../../pools/USDC/ITokenMessenger.sol"; -import {BurnMintERC20} from "../../../../../shared/token/ERC20/BurnMintERC20.sol"; -import {Router} from "../../../../Router.sol"; import {Pool} from "../../../../libraries/Pool.sol"; import {RateLimiter} from "../../../../libraries/RateLimiter.sol"; - import {TokenPool} from "../../../../pools/TokenPool.sol"; import {HybridLockReleaseUSDCTokenPool} from "../../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; import {USDCTokenPool} from "../../../../pools/USDC/USDCTokenPool.sol"; -import {BaseTest} from "../../../BaseTest.t.sol"; -import {MockE2EUSDCTransmitter} from "../../../mocks/MockE2EUSDCTransmitter.sol"; -import {MockUSDCTokenMessenger} from "../../../mocks/MockUSDCTokenMessenger.sol"; - -contract USDCTokenPoolSetup is BaseTest { - IBurnMintERC20 internal s_token; - MockUSDCTokenMessenger internal s_mockUSDC; - MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; - uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; - - struct USDCMessage { - uint32 version; - uint32 sourceDomain; - uint32 destinationDomain; - uint64 nonce; - bytes32 sender; - bytes32 recipient; - bytes32 destinationCaller; - bytes messageBody; - } - - uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; - uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; - - bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); - address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); - address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); - address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); - - address internal s_routerAllowedOnRamp = address(3456); - address internal s_routerAllowedOffRamp = address(234); - Router internal s_router; - - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; - address[] internal s_allowedList; - - function setUp() public virtual override { - BaseTest.setUp(); - BurnMintERC20 usdcToken = new BurnMintERC20("LINK", "LNK", 18, 0, 0); - s_token = usdcToken; - deal(address(s_token), OWNER, type(uint256).max); - _setUpRamps(); - - s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); - s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); - - s_usdcTokenPool = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - s_usdcTokenPoolTransferLiquidity = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); - usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); - - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(address(s_token)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - chainUpdates[1] = TokenPool.ChainUpdate({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - - s_usdcTokenPool.applyChainUpdates(chainUpdates); - - USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); - domains[0] = USDCTokenPool.DomainUpdate({ - destChainSelector: DEST_CHAIN_SELECTOR, - domainIdentifier: 9999, - allowedCaller: keccak256("allowedCaller"), - enabled: true - }); - - s_usdcTokenPool.setDomains(domains); - - vm.expectEmit(); - emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); - - s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); - s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); - } - - function _setUpRamps() internal { - s_router = new Router(address(s_token), address(s_mockRMN)); - - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); - onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); - address[] memory offRamps = new address[](1); - offRamps[0] = s_routerAllowedOffRamp; - offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); - - s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); - } - - function _generateUSDCMessage( - USDCMessage memory usdcMessage - ) internal pure returns (bytes memory) { - return abi.encodePacked( - usdcMessage.version, - usdcMessage.sourceDomain, - usdcMessage.destinationDomain, - usdcMessage.nonce, - usdcMessage.sender, - usdcMessage.recipient, - usdcMessage.destinationCaller, - usdcMessage.messageBody - ); - } -} +import {HybridLockReleaseUSDCTokenPoolSetup} from "./HybridLockReleaseUSDCTokenPoolSetup.t.sol"; -contract HybridLockReleaseUSDCTokenPool_lockOrBurn is USDCTokenPoolSetup { +contract HybridLockReleaseUSDCTokenPool_lockOrBurn is HybridLockReleaseUSDCTokenPoolSetup { function test_onLockReleaseMechanism_Success() public { bytes32 receiver = bytes32(uint256(uint160(STRANGER))); @@ -217,7 +91,7 @@ contract HybridLockReleaseUSDCTokenPool_lockOrBurn is USDCTokenPoolSetup { assertEq(s_mockUSDC.s_nonce() - 1, nonce); } - function test_onLockReleaseMechanism_thenswitchToPrimary_Success() public { + function test_onLockReleaseMechanism_thenSwitchToPrimary_Success() public { // Test Enabling the LR mechanism and sending an outgoing message test_PrimaryMechanism_Success(); diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.releaseOrMint.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.releaseOrMint.t.sol index ee6e5dcd443..ea3c581ea52 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.releaseOrMint.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.releaseOrMint.t.sol @@ -1,10 +1,6 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IBurnMintERC20} from "../../../../../shared/token/ERC20/IBurnMintERC20.sol"; - -import {BurnMintERC20} from "../../../../../shared/token/ERC20/BurnMintERC20.sol"; -import {Router} from "../../../../Router.sol"; import {Internal} from "../../../../libraries/Internal.sol"; import {Pool} from "../../../../libraries/Pool.sol"; import {TokenPool} from "../../../../pools/TokenPool.sol"; @@ -12,131 +8,10 @@ import {HybridLockReleaseUSDCTokenPool} from "../../../../pools/USDC/HybridLockR import {LOCK_RELEASE_FLAG} from "../../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; import {USDCBridgeMigrator} from "../../../../pools/USDC/USDCBridgeMigrator.sol"; import {USDCTokenPool} from "../../../../pools/USDC/USDCTokenPool.sol"; -import {BaseTest} from "../../../BaseTest.t.sol"; import {MockE2EUSDCTransmitter} from "../../../mocks/MockE2EUSDCTransmitter.sol"; -import {MockUSDCTokenMessenger} from "../../../mocks/MockUSDCTokenMessenger.sol"; - -contract USDCTokenPoolSetup is BaseTest { - IBurnMintERC20 internal s_token; - MockUSDCTokenMessenger internal s_mockUSDC; - MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; - uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; - - struct USDCMessage { - uint32 version; - uint32 sourceDomain; - uint32 destinationDomain; - uint64 nonce; - bytes32 sender; - bytes32 recipient; - bytes32 destinationCaller; - bytes messageBody; - } - - uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; - uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; - - bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); - address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); - address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); - address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); - - address internal s_routerAllowedOnRamp = address(3456); - address internal s_routerAllowedOffRamp = address(234); - Router internal s_router; - - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; - address[] internal s_allowedList; - - function setUp() public virtual override { - BaseTest.setUp(); - BurnMintERC20 usdcToken = new BurnMintERC20("LINK", "LNK", 18, 0, 0); - s_token = usdcToken; - deal(address(s_token), OWNER, type(uint256).max); - _setUpRamps(); - - s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); - s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); - - s_usdcTokenPool = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - s_usdcTokenPoolTransferLiquidity = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); - usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); - - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(address(s_token)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - chainUpdates[1] = TokenPool.ChainUpdate({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - - s_usdcTokenPool.applyChainUpdates(chainUpdates); - - USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); - domains[0] = USDCTokenPool.DomainUpdate({ - destChainSelector: DEST_CHAIN_SELECTOR, - domainIdentifier: 9999, - allowedCaller: keccak256("allowedCaller"), - enabled: true - }); - - s_usdcTokenPool.setDomains(domains); - - vm.expectEmit(); - emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); - - s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); - s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); - } - - function _setUpRamps() internal { - s_router = new Router(address(s_token), address(s_mockRMN)); - - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); - onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); - address[] memory offRamps = new address[](1); - offRamps[0] = s_routerAllowedOffRamp; - offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); - - s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); - } - - function _generateUSDCMessage( - USDCMessage memory usdcMessage - ) internal pure returns (bytes memory) { - return abi.encodePacked( - usdcMessage.version, - usdcMessage.sourceDomain, - usdcMessage.destinationDomain, - usdcMessage.nonce, - usdcMessage.sender, - usdcMessage.recipient, - usdcMessage.destinationCaller, - usdcMessage.messageBody - ); - } -} +import {HybridLockReleaseUSDCTokenPoolSetup} from "./HybridLockReleaseUSDCTokenPoolSetup.t.sol"; -contract HybridLockReleaseUSDCTokenPool_releaseOrMint is USDCTokenPoolSetup { +contract HybridLockReleaseUSDCTokenPool_releaseOrMint is HybridLockReleaseUSDCTokenPoolSetup { function test_OnLockReleaseMechanism_Success() public { address recipient = address(1234); diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.transferLiquidity.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.transferLiquidity.t.sol index 699a7f00810..4e5a45a1438 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.transferLiquidity.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.transferLiquidity.t.sol @@ -2,139 +2,11 @@ pragma solidity 0.8.24; import {ILiquidityContainer} from "../../../../../liquiditymanager/interfaces/ILiquidityContainer.sol"; -import {IBurnMintERC20} from "../../../../../shared/token/ERC20/IBurnMintERC20.sol"; -import {BurnMintERC20} from "../../../../../shared/token/ERC20/BurnMintERC20.sol"; -import {Router} from "../../../../Router.sol"; - -import {TokenPool} from "../../../../pools/TokenPool.sol"; import {HybridLockReleaseUSDCTokenPool} from "../../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; -import {USDCTokenPool} from "../../../../pools/USDC/USDCTokenPool.sol"; -import {BaseTest} from "../../../BaseTest.t.sol"; -import {MockE2EUSDCTransmitter} from "../../../mocks/MockE2EUSDCTransmitter.sol"; -import {MockUSDCTokenMessenger} from "../../../mocks/MockUSDCTokenMessenger.sol"; - -contract USDCTokenPoolSetup is BaseTest { - IBurnMintERC20 internal s_token; - MockUSDCTokenMessenger internal s_mockUSDC; - MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; - uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; - - struct USDCMessage { - uint32 version; - uint32 sourceDomain; - uint32 destinationDomain; - uint64 nonce; - bytes32 sender; - bytes32 recipient; - bytes32 destinationCaller; - bytes messageBody; - } - - uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; - uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; - - bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); - address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); - address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); - address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); - - address internal s_routerAllowedOnRamp = address(3456); - address internal s_routerAllowedOffRamp = address(234); - Router internal s_router; - - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; - address[] internal s_allowedList; - - function setUp() public virtual override { - BaseTest.setUp(); - BurnMintERC20 usdcToken = new BurnMintERC20("LINK", "LNK", 18, 0, 0); - s_token = usdcToken; - deal(address(s_token), OWNER, type(uint256).max); - _setUpRamps(); - - s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); - s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); - - s_usdcTokenPool = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - s_usdcTokenPoolTransferLiquidity = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); - usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); - - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(address(s_token)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - chainUpdates[1] = TokenPool.ChainUpdate({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - - s_usdcTokenPool.applyChainUpdates(chainUpdates); - - USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); - domains[0] = USDCTokenPool.DomainUpdate({ - destChainSelector: DEST_CHAIN_SELECTOR, - domainIdentifier: 9999, - allowedCaller: keccak256("allowedCaller"), - enabled: true - }); - - s_usdcTokenPool.setDomains(domains); - - vm.expectEmit(); - emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); - - s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); - s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); - } - - function _setUpRamps() internal { - s_router = new Router(address(s_token), address(s_mockRMN)); - - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); - onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); - address[] memory offRamps = new address[](1); - offRamps[0] = s_routerAllowedOffRamp; - offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); - - s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); - } - - function _generateUSDCMessage( - USDCMessage memory usdcMessage - ) internal pure returns (bytes memory) { - return abi.encodePacked( - usdcMessage.version, - usdcMessage.sourceDomain, - usdcMessage.destinationDomain, - usdcMessage.nonce, - usdcMessage.sender, - usdcMessage.recipient, - usdcMessage.destinationCaller, - usdcMessage.messageBody - ); - } -} +import {HybridLockReleaseUSDCTokenPoolSetup} from "./HybridLockReleaseUSDCTokenPoolSetup.t.sol"; -contract HybridLockReleaseUSDCTokenPool_TransferLiquidity is USDCTokenPoolSetup { +contract HybridLockReleaseUSDCTokenPool_TransferLiquidity is HybridLockReleaseUSDCTokenPoolSetup { function test_transferLiquidity_Success() public { // Set as the OWNER so we can provide liquidity vm.startPrank(OWNER); diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPoolSetup.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPoolSetup.t.sol new file mode 100644 index 00000000000..004c71ccd02 --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/USDC/HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPoolSetup.t.sol @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IBurnMintERC20} from "../../../../../shared/token/ERC20/IBurnMintERC20.sol"; + +import {BurnMintERC677} from "../../../../../shared/token/ERC677/BurnMintERC677.sol"; +import {Router} from "../../../../Router.sol"; +import {TokenPool} from "../../../../pools/TokenPool.sol"; +import {HybridLockReleaseUSDCTokenPool} from "../../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; +import {USDCTokenPool} from "../../../../pools/USDC/USDCTokenPool.sol"; +import {BaseTest} from "../../../BaseTest.t.sol"; +import {MockE2EUSDCTransmitter} from "../../../mocks/MockE2EUSDCTransmitter.sol"; +import {MockUSDCTokenMessenger} from "../../../mocks/MockUSDCTokenMessenger.sol"; + +contract HybridLockReleaseUSDCTokenPoolSetup is BaseTest { + IBurnMintERC20 internal s_token; + MockUSDCTokenMessenger internal s_mockUSDC; + MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; + uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; + + struct USDCMessage { + uint32 version; + uint32 sourceDomain; + uint32 destinationDomain; + uint64 nonce; + bytes32 sender; + bytes32 recipient; + bytes32 destinationCaller; + bytes messageBody; + } + + uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; + uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; + + bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); + address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); + address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); + address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); + + address internal s_routerAllowedOnRamp = address(3456); + address internal s_routerAllowedOffRamp = address(234); + Router internal s_router; + + HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; + HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; + address[] internal s_allowedList; + + function setUp() public virtual override { + BaseTest.setUp(); + BurnMintERC677 usdcToken = new BurnMintERC677("LINK", "LNK", 18, 0); + s_token = usdcToken; + deal(address(s_token), OWNER, type(uint256).max); + _setUpRamps(); + + s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); + s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); + + usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); + + s_usdcTokenPool = + new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); + + s_usdcTokenPoolTransferLiquidity = + new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); + + usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); + usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); + + bytes[] memory sourcePoolAddresses = new bytes[](1); + sourcePoolAddresses[0] = abi.encode(SOURCE_CHAIN_USDC_POOL); + + bytes[] memory destPoolAddresses = new bytes[](1); + destPoolAddresses[0] = abi.encode(DEST_CHAIN_USDC_POOL); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + remotePoolAddresses: sourcePoolAddresses, + remoteTokenAddress: abi.encode(address(s_token)), + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() + }); + chainUpdates[1] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddresses: destPoolAddresses, + remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() + }); + + s_usdcTokenPool.applyChainUpdates(new uint64[](0), chainUpdates); + + USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); + domains[0] = USDCTokenPool.DomainUpdate({ + destChainSelector: DEST_CHAIN_SELECTOR, + domainIdentifier: 9999, + allowedCaller: keccak256("allowedCaller"), + enabled: true + }); + + s_usdcTokenPool.setDomains(domains); + + vm.expectEmit(); + emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); + + s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); + s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); + } + + function _setUpRamps() internal { + s_router = new Router(address(s_token), address(s_mockRMN)); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + address[] memory offRamps = new address[](1); + offRamps[0] = s_routerAllowedOffRamp; + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); + + s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } + + function _generateUSDCMessage( + USDCMessage memory usdcMessage + ) internal pure returns (bytes memory) { + return abi.encodePacked( + usdcMessage.version, + usdcMessage.sourceDomain, + usdcMessage.destinationDomain, + usdcMessage.nonce, + usdcMessage.sender, + usdcMessage.recipient, + usdcMessage.destinationCaller, + usdcMessage.messageBody + ); + } +} diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.burnLockedUSDC.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.burnLockedUSDC.t.sol index 7425b087401..52ddb9dad4c 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.burnLockedUSDC.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.burnLockedUSDC.t.sol @@ -1,142 +1,12 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IBurnMintERC20} from "../../../../../shared/token/ERC20/IBurnMintERC20.sol"; - -import {BurnMintERC20} from "../../../../../shared/token/ERC20/BurnMintERC20.sol"; -import {Router} from "../../../../Router.sol"; import {Pool} from "../../../../libraries/Pool.sol"; - import {TokenPool} from "../../../../pools/TokenPool.sol"; -import {HybridLockReleaseUSDCTokenPool} from "../../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; import {USDCBridgeMigrator} from "../../../../pools/USDC/USDCBridgeMigrator.sol"; -import {USDCTokenPool} from "../../../../pools/USDC/USDCTokenPool.sol"; -import {BaseTest} from "../../../BaseTest.t.sol"; -import {MockE2EUSDCTransmitter} from "../../../mocks/MockE2EUSDCTransmitter.sol"; -import {MockUSDCTokenMessenger} from "../../../mocks/MockUSDCTokenMessenger.sol"; import {HybridLockReleaseUSDCTokenPool_lockOrBurn} from "../HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.lockOrBurn.t.sol"; -contract USDCTokenPoolSetup is BaseTest { - IBurnMintERC20 internal s_token; - MockUSDCTokenMessenger internal s_mockUSDC; - MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; - uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; - - struct USDCMessage { - uint32 version; - uint32 sourceDomain; - uint32 destinationDomain; - uint64 nonce; - bytes32 sender; - bytes32 recipient; - bytes32 destinationCaller; - bytes messageBody; - } - - uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; - uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; - - bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); - address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); - address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); - address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); - - address internal s_routerAllowedOnRamp = address(3456); - address internal s_routerAllowedOffRamp = address(234); - Router internal s_router; - - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; - address[] internal s_allowedList; - - function setUp() public virtual override { - BaseTest.setUp(); - BurnMintERC20 usdcToken = new BurnMintERC20("LINK", "LNK", 18, 0, 0); - s_token = usdcToken; - deal(address(s_token), OWNER, type(uint256).max); - _setUpRamps(); - - s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); - s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); - - s_usdcTokenPool = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - s_usdcTokenPoolTransferLiquidity = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); - usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); - - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(address(s_token)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - chainUpdates[1] = TokenPool.ChainUpdate({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - - s_usdcTokenPool.applyChainUpdates(chainUpdates); - - USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); - domains[0] = USDCTokenPool.DomainUpdate({ - destChainSelector: DEST_CHAIN_SELECTOR, - domainIdentifier: 9999, - allowedCaller: keccak256("allowedCaller"), - enabled: true - }); - - s_usdcTokenPool.setDomains(domains); - - vm.expectEmit(); - emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); - - s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); - s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); - } - - function _setUpRamps() internal { - s_router = new Router(address(s_token), address(s_mockRMN)); - - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); - onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); - address[] memory offRamps = new address[](1); - offRamps[0] = s_routerAllowedOffRamp; - offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); - - s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); - } - - function _generateUSDCMessage( - USDCMessage memory usdcMessage - ) internal pure returns (bytes memory) { - return abi.encodePacked( - usdcMessage.version, - usdcMessage.sourceDomain, - usdcMessage.destinationDomain, - usdcMessage.nonce, - usdcMessage.sender, - usdcMessage.recipient, - usdcMessage.destinationCaller, - usdcMessage.messageBody - ); - } -} - contract USDCBridgeMigrator_BurnLockedUSDC is HybridLockReleaseUSDCTokenPool_lockOrBurn { function test_lockOrBurn_then_BurnInCCTPMigration_Success() public { bytes32 receiver = bytes32(uint256(uint160(STRANGER))); diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.cancelMigrationProposal.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.cancelMigrationProposal.t.sol index 68b88b12c14..6ec63cc8e9e 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.cancelMigrationProposal.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.cancelMigrationProposal.t.sol @@ -1,140 +1,10 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IBurnMintERC20} from "../../../../../shared/token/ERC20/IBurnMintERC20.sol"; - -import {BurnMintERC20} from "../../../../../shared/token/ERC20/BurnMintERC20.sol"; -import {Router} from "../../../../Router.sol"; - -import {TokenPool} from "../../../../pools/TokenPool.sol"; -import {HybridLockReleaseUSDCTokenPool} from "../../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; import {USDCBridgeMigrator} from "../../../../pools/USDC/USDCBridgeMigrator.sol"; -import {USDCTokenPool} from "../../../../pools/USDC/USDCTokenPool.sol"; -import {BaseTest} from "../../../BaseTest.t.sol"; -import {MockE2EUSDCTransmitter} from "../../../mocks/MockE2EUSDCTransmitter.sol"; -import {MockUSDCTokenMessenger} from "../../../mocks/MockUSDCTokenMessenger.sol"; - -contract USDCTokenPoolSetup is BaseTest { - IBurnMintERC20 internal s_token; - MockUSDCTokenMessenger internal s_mockUSDC; - MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; - uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; - - struct USDCMessage { - uint32 version; - uint32 sourceDomain; - uint32 destinationDomain; - uint64 nonce; - bytes32 sender; - bytes32 recipient; - bytes32 destinationCaller; - bytes messageBody; - } - - uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; - uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; - - bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); - address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); - address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); - address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); - - address internal s_routerAllowedOnRamp = address(3456); - address internal s_routerAllowedOffRamp = address(234); - Router internal s_router; - - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; - address[] internal s_allowedList; - - function setUp() public virtual override { - BaseTest.setUp(); - BurnMintERC20 usdcToken = new BurnMintERC20("LINK", "LNK", 18, 0, 0); - s_token = usdcToken; - deal(address(s_token), OWNER, type(uint256).max); - _setUpRamps(); - - s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); - s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); - - s_usdcTokenPool = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - s_usdcTokenPoolTransferLiquidity = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); - usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); - - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(address(s_token)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - chainUpdates[1] = TokenPool.ChainUpdate({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - - s_usdcTokenPool.applyChainUpdates(chainUpdates); - - USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); - domains[0] = USDCTokenPool.DomainUpdate({ - destChainSelector: DEST_CHAIN_SELECTOR, - domainIdentifier: 9999, - allowedCaller: keccak256("allowedCaller"), - enabled: true - }); - - s_usdcTokenPool.setDomains(domains); - - vm.expectEmit(); - emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); - - s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); - s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); - } - - function _setUpRamps() internal { - s_router = new Router(address(s_token), address(s_mockRMN)); - - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); - onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); - address[] memory offRamps = new address[](1); - offRamps[0] = s_routerAllowedOffRamp; - offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); - - s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); - } - - function _generateUSDCMessage( - USDCMessage memory usdcMessage - ) internal pure returns (bytes memory) { - return abi.encodePacked( - usdcMessage.version, - usdcMessage.sourceDomain, - usdcMessage.destinationDomain, - usdcMessage.nonce, - usdcMessage.sender, - usdcMessage.recipient, - usdcMessage.destinationCaller, - usdcMessage.messageBody - ); - } -} +import {HybridLockReleaseUSDCTokenPoolSetup} from "../USDCTokenPoolSetup.t.sol"; -contract USDCBridgeMigrator_cancelMigrationProposal is USDCTokenPoolSetup { +contract USDCBridgeMigrator_cancelMigrationProposal is HybridLockReleaseUSDCTokenPoolSetup { function test_cancelExistingCCTPMigrationProposal_Success() public { vm.startPrank(OWNER); diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.excludeTokensFromBurn.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.excludeTokensFromBurn.t.sol index 39e42007d5c..76e87f09852 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.excludeTokensFromBurn.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.excludeTokensFromBurn.t.sol @@ -1,140 +1,10 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IBurnMintERC20} from "../../../../../shared/token/ERC20/IBurnMintERC20.sol"; - -import {BurnMintERC20} from "../../../../../shared/token/ERC20/BurnMintERC20.sol"; -import {Router} from "../../../../Router.sol"; - -import {TokenPool} from "../../../../pools/TokenPool.sol"; -import {HybridLockReleaseUSDCTokenPool} from "../../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; import {USDCBridgeMigrator} from "../../../../pools/USDC/USDCBridgeMigrator.sol"; -import {USDCTokenPool} from "../../../../pools/USDC/USDCTokenPool.sol"; -import {BaseTest} from "../../../BaseTest.t.sol"; -import {MockE2EUSDCTransmitter} from "../../../mocks/MockE2EUSDCTransmitter.sol"; -import {MockUSDCTokenMessenger} from "../../../mocks/MockUSDCTokenMessenger.sol"; - -contract USDCTokenPoolSetup is BaseTest { - IBurnMintERC20 internal s_token; - MockUSDCTokenMessenger internal s_mockUSDC; - MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; - uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; - - struct USDCMessage { - uint32 version; - uint32 sourceDomain; - uint32 destinationDomain; - uint64 nonce; - bytes32 sender; - bytes32 recipient; - bytes32 destinationCaller; - bytes messageBody; - } - - uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; - uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; - - bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); - address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); - address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); - address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); - - address internal s_routerAllowedOnRamp = address(3456); - address internal s_routerAllowedOffRamp = address(234); - Router internal s_router; - - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; - address[] internal s_allowedList; - - function setUp() public virtual override { - BaseTest.setUp(); - BurnMintERC20 usdcToken = new BurnMintERC20("LINK", "LNK", 18, 0, 0); - s_token = usdcToken; - deal(address(s_token), OWNER, type(uint256).max); - _setUpRamps(); - - s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); - s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); - - s_usdcTokenPool = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - s_usdcTokenPoolTransferLiquidity = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); - usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); - - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(address(s_token)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - chainUpdates[1] = TokenPool.ChainUpdate({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - - s_usdcTokenPool.applyChainUpdates(chainUpdates); - - USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); - domains[0] = USDCTokenPool.DomainUpdate({ - destChainSelector: DEST_CHAIN_SELECTOR, - domainIdentifier: 9999, - allowedCaller: keccak256("allowedCaller"), - enabled: true - }); - - s_usdcTokenPool.setDomains(domains); - - vm.expectEmit(); - emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); - - s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); - s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); - } - - function _setUpRamps() internal { - s_router = new Router(address(s_token), address(s_mockRMN)); - - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); - onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); - address[] memory offRamps = new address[](1); - offRamps[0] = s_routerAllowedOffRamp; - offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); - - s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); - } - - function _generateUSDCMessage( - USDCMessage memory usdcMessage - ) internal pure returns (bytes memory) { - return abi.encodePacked( - usdcMessage.version, - usdcMessage.sourceDomain, - usdcMessage.destinationDomain, - usdcMessage.nonce, - usdcMessage.sender, - usdcMessage.recipient, - usdcMessage.destinationCaller, - usdcMessage.messageBody - ); - } -} +import {HybridLockReleaseUSDCTokenPoolSetup} from "../USDCTokenPoolSetup.t.sol"; -contract USDCBridgeMigrator_excludeTokensFromBurn is USDCTokenPoolSetup { +contract USDCBridgeMigrator_excludeTokensFromBurn is HybridLockReleaseUSDCTokenPoolSetup { function test_excludeTokensWhenNoMigrationProposalPending_Revert() public { vm.expectRevert(abi.encodeWithSelector(USDCBridgeMigrator.NoMigrationProposalPending.selector)); diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.proposeMigration.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.proposeMigration.t.sol index 6e717029927..dd7ad2c2bf0 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.proposeMigration.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.proposeMigration.t.sol @@ -1,140 +1,10 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IBurnMintERC20} from "../../../../../shared/token/ERC20/IBurnMintERC20.sol"; - -import {BurnMintERC20} from "../../../../../shared/token/ERC20/BurnMintERC20.sol"; -import {Router} from "../../../../Router.sol"; - -import {TokenPool} from "../../../../pools/TokenPool.sol"; -import {HybridLockReleaseUSDCTokenPool} from "../../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; import {USDCBridgeMigrator} from "../../../../pools/USDC/USDCBridgeMigrator.sol"; -import {USDCTokenPool} from "../../../../pools/USDC/USDCTokenPool.sol"; -import {BaseTest} from "../../../BaseTest.t.sol"; -import {MockE2EUSDCTransmitter} from "../../../mocks/MockE2EUSDCTransmitter.sol"; -import {MockUSDCTokenMessenger} from "../../../mocks/MockUSDCTokenMessenger.sol"; - -contract USDCTokenPoolSetup is BaseTest { - IBurnMintERC20 internal s_token; - MockUSDCTokenMessenger internal s_mockUSDC; - MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; - uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; - - struct USDCMessage { - uint32 version; - uint32 sourceDomain; - uint32 destinationDomain; - uint64 nonce; - bytes32 sender; - bytes32 recipient; - bytes32 destinationCaller; - bytes messageBody; - } - - uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; - uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; - - bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); - address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); - address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); - address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); - - address internal s_routerAllowedOnRamp = address(3456); - address internal s_routerAllowedOffRamp = address(234); - Router internal s_router; - - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; - address[] internal s_allowedList; - - function setUp() public virtual override { - BaseTest.setUp(); - BurnMintERC20 usdcToken = new BurnMintERC20("LINK", "LNK", 18, 0, 0); - s_token = usdcToken; - deal(address(s_token), OWNER, type(uint256).max); - _setUpRamps(); - - s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); - s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); - - s_usdcTokenPool = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - s_usdcTokenPoolTransferLiquidity = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); - usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); - - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(address(s_token)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - chainUpdates[1] = TokenPool.ChainUpdate({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - - s_usdcTokenPool.applyChainUpdates(chainUpdates); - - USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); - domains[0] = USDCTokenPool.DomainUpdate({ - destChainSelector: DEST_CHAIN_SELECTOR, - domainIdentifier: 9999, - allowedCaller: keccak256("allowedCaller"), - enabled: true - }); - - s_usdcTokenPool.setDomains(domains); - - vm.expectEmit(); - emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); - - s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); - s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); - } - - function _setUpRamps() internal { - s_router = new Router(address(s_token), address(s_mockRMN)); - - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); - onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); - address[] memory offRamps = new address[](1); - offRamps[0] = s_routerAllowedOffRamp; - offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); - - s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); - } - - function _generateUSDCMessage( - USDCMessage memory usdcMessage - ) internal pure returns (bytes memory) { - return abi.encodePacked( - usdcMessage.version, - usdcMessage.sourceDomain, - usdcMessage.destinationDomain, - usdcMessage.nonce, - usdcMessage.sender, - usdcMessage.recipient, - usdcMessage.destinationCaller, - usdcMessage.messageBody - ); - } -} +import {HybridLockReleaseUSDCTokenPoolSetup} from "../USDCTokenPoolSetup.t.sol"; -contract USDCBridgeMigrator_proposeMigration is USDCTokenPoolSetup { +contract USDCBridgeMigrator_proposeMigration is HybridLockReleaseUSDCTokenPoolSetup { function test_ChainNotUsingLockRelease_Revert() public { vm.expectRevert(abi.encodeWithSelector(USDCBridgeMigrator.InvalidChainSelector.selector)); diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.provideLiquidity.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.provideLiquidity.t.sol index bf081140e3d..88196d87795 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.provideLiquidity.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.provideLiquidity.t.sol @@ -1,139 +1,10 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IBurnMintERC20} from "../../../../../shared/token/ERC20/IBurnMintERC20.sol"; - -import {BurnMintERC20} from "../../../../../shared/token/ERC20/BurnMintERC20.sol"; -import {Router} from "../../../../Router.sol"; - import {TokenPool} from "../../../../pools/TokenPool.sol"; import {HybridLockReleaseUSDCTokenPool} from "../../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; -import {USDCTokenPool} from "../../../../pools/USDC/USDCTokenPool.sol"; -import {BaseTest} from "../../../BaseTest.t.sol"; -import {MockE2EUSDCTransmitter} from "../../../mocks/MockE2EUSDCTransmitter.sol"; -import {MockUSDCTokenMessenger} from "../../../mocks/MockUSDCTokenMessenger.sol"; import {USDCBridgeMigrator_BurnLockedUSDC} from "./USDCBridgeMigrator.burnLockedUSDC.t.sol"; -contract USDCTokenPoolSetup is BaseTest { - IBurnMintERC20 internal s_token; - MockUSDCTokenMessenger internal s_mockUSDC; - MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; - uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; - - struct USDCMessage { - uint32 version; - uint32 sourceDomain; - uint32 destinationDomain; - uint64 nonce; - bytes32 sender; - bytes32 recipient; - bytes32 destinationCaller; - bytes messageBody; - } - - uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; - uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; - - bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); - address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); - address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); - address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); - - address internal s_routerAllowedOnRamp = address(3456); - address internal s_routerAllowedOffRamp = address(234); - Router internal s_router; - - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; - address[] internal s_allowedList; - - function setUp() public virtual override { - BaseTest.setUp(); - BurnMintERC20 usdcToken = new BurnMintERC20("LINK", "LNK", 18, 0, 0); - s_token = usdcToken; - deal(address(s_token), OWNER, type(uint256).max); - _setUpRamps(); - - s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); - s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); - - s_usdcTokenPool = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - s_usdcTokenPoolTransferLiquidity = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); - usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); - - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(address(s_token)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - chainUpdates[1] = TokenPool.ChainUpdate({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - - s_usdcTokenPool.applyChainUpdates(chainUpdates); - - USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); - domains[0] = USDCTokenPool.DomainUpdate({ - destChainSelector: DEST_CHAIN_SELECTOR, - domainIdentifier: 9999, - allowedCaller: keccak256("allowedCaller"), - enabled: true - }); - - s_usdcTokenPool.setDomains(domains); - - vm.expectEmit(); - emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); - - s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); - s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); - } - - function _setUpRamps() internal { - s_router = new Router(address(s_token), address(s_mockRMN)); - - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); - onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); - address[] memory offRamps = new address[](1); - offRamps[0] = s_routerAllowedOffRamp; - offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); - - s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); - } - - function _generateUSDCMessage( - USDCMessage memory usdcMessage - ) internal pure returns (bytes memory) { - return abi.encodePacked( - usdcMessage.version, - usdcMessage.sourceDomain, - usdcMessage.destinationDomain, - usdcMessage.nonce, - usdcMessage.sender, - usdcMessage.recipient, - usdcMessage.destinationCaller, - usdcMessage.messageBody - ); - } -} - contract USDCBridgeMigrator_provideLiquidity is USDCBridgeMigrator_BurnLockedUSDC { function test_cannotModifyLiquidityWithoutPermissions_Revert() public { address randomAddr = makeAddr("RANDOM"); diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.releaseOrMint.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.releaseOrMint.t.sol index df955abc9c3..40569603e96 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.releaseOrMint.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.releaseOrMint.t.sol @@ -1,144 +1,15 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IBurnMintERC20} from "../../../../../shared/token/ERC20/IBurnMintERC20.sol"; - -import {BurnMintERC20} from "../../../../../shared/token/ERC20/BurnMintERC20.sol"; -import {Router} from "../../../../Router.sol"; import {Internal} from "../../../../libraries/Internal.sol"; import {Pool} from "../../../../libraries/Pool.sol"; - import {TokenPool} from "../../../../pools/TokenPool.sol"; -import {HybridLockReleaseUSDCTokenPool} from "../../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; import {LOCK_RELEASE_FLAG} from "../../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; import {USDCBridgeMigrator} from "../../../../pools/USDC/USDCBridgeMigrator.sol"; import {USDCTokenPool} from "../../../../pools/USDC/USDCTokenPool.sol"; -import {BaseTest} from "../../../BaseTest.t.sol"; -import {MockE2EUSDCTransmitter} from "../../../mocks/MockE2EUSDCTransmitter.sol"; -import {MockUSDCTokenMessenger} from "../../../mocks/MockUSDCTokenMessenger.sol"; import {HybridLockReleaseUSDCTokenPool_releaseOrMint} from "../HybridLockReleaseUSDCTokenPool/HybridLockReleaseUSDCTokenPool.releaseOrMint.t.sol"; -contract USDCTokenPoolSetup is BaseTest { - IBurnMintERC20 internal s_token; - MockUSDCTokenMessenger internal s_mockUSDC; - MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; - uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; - - struct USDCMessage { - uint32 version; - uint32 sourceDomain; - uint32 destinationDomain; - uint64 nonce; - bytes32 sender; - bytes32 recipient; - bytes32 destinationCaller; - bytes messageBody; - } - - uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; - uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; - - bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); - address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); - address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); - address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); - - address internal s_routerAllowedOnRamp = address(3456); - address internal s_routerAllowedOffRamp = address(234); - Router internal s_router; - - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; - address[] internal s_allowedList; - - function setUp() public virtual override { - BaseTest.setUp(); - BurnMintERC20 usdcToken = new BurnMintERC20("LINK", "LNK", 18, 0, 0); - s_token = usdcToken; - deal(address(s_token), OWNER, type(uint256).max); - _setUpRamps(); - - s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); - s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); - - s_usdcTokenPool = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - s_usdcTokenPoolTransferLiquidity = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); - usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); - - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(address(s_token)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - chainUpdates[1] = TokenPool.ChainUpdate({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - - s_usdcTokenPool.applyChainUpdates(chainUpdates); - - USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); - domains[0] = USDCTokenPool.DomainUpdate({ - destChainSelector: DEST_CHAIN_SELECTOR, - domainIdentifier: 9999, - allowedCaller: keccak256("allowedCaller"), - enabled: true - }); - - s_usdcTokenPool.setDomains(domains); - - vm.expectEmit(); - emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); - - s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); - s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); - } - - function _setUpRamps() internal { - s_router = new Router(address(s_token), address(s_mockRMN)); - - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); - onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); - address[] memory offRamps = new address[](1); - offRamps[0] = s_routerAllowedOffRamp; - offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); - - s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); - } - - function _generateUSDCMessage( - USDCMessage memory usdcMessage - ) internal pure returns (bytes memory) { - return abi.encodePacked( - usdcMessage.version, - usdcMessage.sourceDomain, - usdcMessage.destinationDomain, - usdcMessage.nonce, - usdcMessage.sender, - usdcMessage.recipient, - usdcMessage.destinationCaller, - usdcMessage.messageBody - ); - } -} - contract USDCBridgeMigrator_releaseOrMint is HybridLockReleaseUSDCTokenPool_releaseOrMint { function test_unstickManualTxAfterMigration_destChain_Success() public { address recipient = address(1234); diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.updateChainSelectorMechanism.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.updateChainSelectorMechanism.t.sol index ab0ef64b38d..9db74061a31 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.updateChainSelectorMechanism.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDC/USDCBridgeMigrator/USDCBridgeMigrator.updateChainSelectorMechanism.t.sol @@ -1,138 +1,9 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {IBurnMintERC20} from "../../../../../shared/token/ERC20/IBurnMintERC20.sol"; - -import {BurnMintERC20} from "../../../../../shared/token/ERC20/BurnMintERC20.sol"; -import {Router} from "../../../../Router.sol"; - -import {TokenPool} from "../../../../pools/TokenPool.sol"; import {HybridLockReleaseUSDCTokenPool} from "../../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; -import {USDCTokenPool} from "../../../../pools/USDC/USDCTokenPool.sol"; -import {BaseTest} from "../../../BaseTest.t.sol"; -import {MockE2EUSDCTransmitter} from "../../../mocks/MockE2EUSDCTransmitter.sol"; -import {MockUSDCTokenMessenger} from "../../../mocks/MockUSDCTokenMessenger.sol"; -import {USDCBridgeMigrator_BurnLockedUSDC} from "./USDCBridgeMigrator.burnLockedUSDC.t.sol"; - -contract USDCTokenPoolSetup is BaseTest { - IBurnMintERC20 internal s_token; - MockUSDCTokenMessenger internal s_mockUSDC; - MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; - uint32 internal constant USDC_DEST_TOKEN_GAS = 150_000; - - struct USDCMessage { - uint32 version; - uint32 sourceDomain; - uint32 destinationDomain; - uint64 nonce; - bytes32 sender; - bytes32 recipient; - bytes32 destinationCaller; - bytes messageBody; - } - - uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; - uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; - - bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); - address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); - address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); - address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); - - address internal s_routerAllowedOnRamp = address(3456); - address internal s_routerAllowedOffRamp = address(234); - Router internal s_router; - - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; - HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; - address[] internal s_allowedList; - - function setUp() public virtual override { - BaseTest.setUp(); - BurnMintERC20 usdcToken = new BurnMintERC20("LINK", "LNK", 18, 0, 0); - s_token = usdcToken; - deal(address(s_token), OWNER, type(uint256).max); - _setUpRamps(); - - s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); - s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); - - s_usdcTokenPool = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - s_usdcTokenPoolTransferLiquidity = - new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); - - usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); - usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); - TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); - chainUpdates[0] = TokenPool.ChainUpdate({ - remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(address(s_token)), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - chainUpdates[1] = TokenPool.ChainUpdate({ - remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), - remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), - allowed: true, - outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), - inboundRateLimiterConfig: _getInboundRateLimiterConfig() - }); - - s_usdcTokenPool.applyChainUpdates(chainUpdates); - - USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); - domains[0] = USDCTokenPool.DomainUpdate({ - destChainSelector: DEST_CHAIN_SELECTOR, - domainIdentifier: 9999, - allowedCaller: keccak256("allowedCaller"), - enabled: true - }); - - s_usdcTokenPool.setDomains(domains); - - vm.expectEmit(); - emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); - - s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); - s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); - } - - function _setUpRamps() internal { - s_router = new Router(address(s_token), address(s_mockRMN)); - - Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); - onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); - Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); - address[] memory offRamps = new address[](1); - offRamps[0] = s_routerAllowedOffRamp; - offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); - - s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); - } - - function _generateUSDCMessage( - USDCMessage memory usdcMessage - ) internal pure returns (bytes memory) { - return abi.encodePacked( - usdcMessage.version, - usdcMessage.sourceDomain, - usdcMessage.destinationDomain, - usdcMessage.nonce, - usdcMessage.sender, - usdcMessage.recipient, - usdcMessage.destinationCaller, - usdcMessage.messageBody - ); - } -} +import {USDCBridgeMigrator_BurnLockedUSDC} from "./USDCBridgeMigrator.burnLockedUSDC.t.sol"; contract USDCBridgeMigrator_updateChainSelectorMechanism is USDCBridgeMigrator_BurnLockedUSDC { function test_cannotRevertChainMechanism_afterMigration_Revert() public { diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/USDCTokenPool/USDCTokenPool.lockOrBurn.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/USDCTokenPool/USDCTokenPool.lockOrBurn.t.sol index 9be60c97218..03d328b8e8c 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDC/USDCTokenPool/USDCTokenPool.lockOrBurn.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDC/USDCTokenPool/USDCTokenPool.lockOrBurn.t.sol @@ -142,14 +142,13 @@ contract USDCTokenPool_lockOrBurn is USDCTokenPoolSetup { TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](1); chainUpdates[0] = TokenPool.ChainUpdate({ remoteChainSelector: wrongDomain, - remotePoolAddress: abi.encode(address(1)), + remotePoolAddresses: new bytes[](0), remoteTokenAddress: abi.encode(address(2)), - allowed: true, outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); - s_usdcTokenPool.applyChainUpdates(chainUpdates); + s_usdcTokenPool.applyChainUpdates(new uint64[](0), chainUpdates); uint256 amount = 1000; vm.startPrank(s_routerAllowedOnRamp); diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/USDCTokenPool/USDCTokenPoolSetup.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/USDCTokenPool/USDCTokenPoolSetup.t.sol index 5d44b90b461..26dd4a0a71b 100644 --- a/contracts/src/v0.8/ccip/test/pools/USDC/USDCTokenPool/USDCTokenPoolSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/pools/USDC/USDCTokenPool/USDCTokenPoolSetup.t.sol @@ -65,26 +65,30 @@ contract USDCTokenPoolSetup is BaseTest { s_usdcTokenPoolWithAllowList = new USDCTokenPoolHelper(s_mockUSDC, s_token, s_allowedList, address(s_mockRMN), address(s_router)); + bytes[] memory sourcePoolAddresses = new bytes[](1); + sourcePoolAddresses[0] = abi.encode(SOURCE_CHAIN_USDC_POOL); + + bytes[] memory destPoolAddresses = new bytes[](1); + destPoolAddresses[0] = abi.encode(DEST_CHAIN_USDC_POOL); + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); chainUpdates[0] = TokenPool.ChainUpdate({ remoteChainSelector: SOURCE_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(SOURCE_CHAIN_USDC_POOL), + remotePoolAddresses: sourcePoolAddresses, remoteTokenAddress: abi.encode(address(s_token)), - allowed: true, outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); chainUpdates[1] = TokenPool.ChainUpdate({ remoteChainSelector: DEST_CHAIN_SELECTOR, - remotePoolAddress: abi.encode(DEST_CHAIN_USDC_POOL), + remotePoolAddresses: destPoolAddresses, remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), - allowed: true, outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), inboundRateLimiterConfig: _getInboundRateLimiterConfig() }); - s_usdcTokenPool.applyChainUpdates(chainUpdates); - s_usdcTokenPoolWithAllowList.applyChainUpdates(chainUpdates); + s_usdcTokenPool.applyChainUpdates(new uint64[](0), chainUpdates); + s_usdcTokenPoolWithAllowList.applyChainUpdates(new uint64[](0), chainUpdates); USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); domains[0] = USDCTokenPool.DomainUpdate({ diff --git a/contracts/src/v0.8/ccip/test/pools/USDC/USDCTokenPoolSetup.t.sol b/contracts/src/v0.8/ccip/test/pools/USDC/USDCTokenPoolSetup.t.sol new file mode 100644 index 00000000000..69712f7c68f --- /dev/null +++ b/contracts/src/v0.8/ccip/test/pools/USDC/USDCTokenPoolSetup.t.sol @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.24; + +import {IBurnMintERC20} from "../../../../shared/token/ERC20/IBurnMintERC20.sol"; + +import {BurnMintERC677} from "../../../../shared/token/ERC677/BurnMintERC677.sol"; +import {Router} from "../../../Router.sol"; +import {TokenPool} from "../../../pools/TokenPool.sol"; +import {HybridLockReleaseUSDCTokenPool} from "../../../pools/USDC/HybridLockReleaseUSDCTokenPool.sol"; +import {USDCTokenPool} from "../../../pools/USDC/USDCTokenPool.sol"; +import {BaseTest} from "../../BaseTest.t.sol"; +import {MockE2EUSDCTransmitter} from "../../mocks/MockE2EUSDCTransmitter.sol"; +import {MockUSDCTokenMessenger} from "../../mocks/MockUSDCTokenMessenger.sol"; + +contract HybridLockReleaseUSDCTokenPoolSetup is BaseTest { + IBurnMintERC20 internal s_token; + MockUSDCTokenMessenger internal s_mockUSDC; + MockE2EUSDCTransmitter internal s_mockUSDCTransmitter; + uint32 internal constant USDC_DEST_TOKEN_GAS = 180_000; + + struct USDCMessage { + uint32 version; + uint32 sourceDomain; + uint32 destinationDomain; + uint64 nonce; + bytes32 sender; + bytes32 recipient; + bytes32 destinationCaller; + bytes messageBody; + } + + uint32 internal constant SOURCE_DOMAIN_IDENTIFIER = 0x02020202; + uint32 internal constant DEST_DOMAIN_IDENTIFIER = 0; + + bytes32 internal constant SOURCE_CHAIN_TOKEN_SENDER = bytes32(uint256(uint160(0x01111111221))); + address internal constant SOURCE_CHAIN_USDC_POOL = address(0x23789765456789); + address internal constant DEST_CHAIN_USDC_POOL = address(0x987384873458734); + address internal constant DEST_CHAIN_USDC_TOKEN = address(0x23598918358198766); + + address internal s_routerAllowedOnRamp = address(3456); + address internal s_routerAllowedOffRamp = address(234); + Router internal s_router; + + HybridLockReleaseUSDCTokenPool internal s_usdcTokenPool; + HybridLockReleaseUSDCTokenPool internal s_usdcTokenPoolTransferLiquidity; + address[] internal s_allowedList; + + function setUp() public virtual override { + BaseTest.setUp(); + BurnMintERC677 usdcToken = new BurnMintERC677("LINK", "LNK", 18, 0); + s_token = usdcToken; + deal(address(s_token), OWNER, type(uint256).max); + _setUpRamps(); + + s_mockUSDCTransmitter = new MockE2EUSDCTransmitter(0, DEST_DOMAIN_IDENTIFIER, address(s_token)); + s_mockUSDC = new MockUSDCTokenMessenger(0, address(s_mockUSDCTransmitter)); + + usdcToken.grantMintAndBurnRoles(address(s_mockUSDCTransmitter)); + + s_usdcTokenPool = + new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); + + s_usdcTokenPoolTransferLiquidity = + new HybridLockReleaseUSDCTokenPool(s_mockUSDC, s_token, new address[](0), address(s_mockRMN), address(s_router)); + + usdcToken.grantMintAndBurnRoles(address(s_mockUSDC)); + usdcToken.grantMintAndBurnRoles(address(s_usdcTokenPool)); + + bytes[] memory sourcePoolAddresses = new bytes[](1); + sourcePoolAddresses[0] = abi.encode(SOURCE_CHAIN_USDC_POOL); + + bytes[] memory destPoolAddresses = new bytes[](1); + destPoolAddresses[0] = abi.encode(DEST_CHAIN_USDC_POOL); + + TokenPool.ChainUpdate[] memory chainUpdates = new TokenPool.ChainUpdate[](2); + chainUpdates[0] = TokenPool.ChainUpdate({ + remoteChainSelector: SOURCE_CHAIN_SELECTOR, + remotePoolAddresses: sourcePoolAddresses, + remoteTokenAddress: abi.encode(address(s_token)), + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() + }); + chainUpdates[1] = TokenPool.ChainUpdate({ + remoteChainSelector: DEST_CHAIN_SELECTOR, + remotePoolAddresses: destPoolAddresses, + remoteTokenAddress: abi.encode(DEST_CHAIN_USDC_TOKEN), + outboundRateLimiterConfig: _getOutboundRateLimiterConfig(), + inboundRateLimiterConfig: _getInboundRateLimiterConfig() + }); + + s_usdcTokenPool.applyChainUpdates(new uint64[](0), chainUpdates); + + USDCTokenPool.DomainUpdate[] memory domains = new USDCTokenPool.DomainUpdate[](1); + domains[0] = USDCTokenPool.DomainUpdate({ + destChainSelector: DEST_CHAIN_SELECTOR, + domainIdentifier: 9999, + allowedCaller: keccak256("allowedCaller"), + enabled: true + }); + + s_usdcTokenPool.setDomains(domains); + + vm.expectEmit(); + emit HybridLockReleaseUSDCTokenPool.LiquidityProviderSet(address(0), OWNER, DEST_CHAIN_SELECTOR); + + s_usdcTokenPool.setLiquidityProvider(DEST_CHAIN_SELECTOR, OWNER); + s_usdcTokenPool.setLiquidityProvider(SOURCE_CHAIN_SELECTOR, OWNER); + } + + function _setUpRamps() internal { + s_router = new Router(address(s_token), address(s_mockRMN)); + + Router.OnRamp[] memory onRampUpdates = new Router.OnRamp[](1); + onRampUpdates[0] = Router.OnRamp({destChainSelector: DEST_CHAIN_SELECTOR, onRamp: s_routerAllowedOnRamp}); + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + address[] memory offRamps = new address[](1); + offRamps[0] = s_routerAllowedOffRamp; + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: SOURCE_CHAIN_SELECTOR, offRamp: offRamps[0]}); + + s_router.applyRampUpdates(onRampUpdates, new Router.OffRamp[](0), offRampUpdates); + } + + function _generateUSDCMessage( + USDCMessage memory usdcMessage + ) internal pure returns (bytes memory) { + return abi.encodePacked( + usdcMessage.version, + usdcMessage.sourceDomain, + usdcMessage.destinationDomain, + usdcMessage.nonce, + usdcMessage.sender, + usdcMessage.recipient, + usdcMessage.destinationCaller, + usdcMessage.messageBody + ); + } +} diff --git a/contracts/src/v0.8/ccip/test/tokenAdminRegistry/TokenPoolFactory/TokenPoolFactory.createTokenPool.t.sol b/contracts/src/v0.8/ccip/test/tokenAdminRegistry/TokenPoolFactory/TokenPoolFactory.createTokenPool.t.sol index 63106f20044..301e26173bf 100644 --- a/contracts/src/v0.8/ccip/test/tokenAdminRegistry/TokenPoolFactory/TokenPoolFactory.createTokenPool.t.sol +++ b/contracts/src/v0.8/ccip/test/tokenAdminRegistry/TokenPoolFactory/TokenPoolFactory.createTokenPool.t.sol @@ -1,11 +1,12 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; -import {Ownable2Step} from "../../../../shared/access/Ownable2Step.sol"; import {IBurnMintERC20} from "../../../../shared/token/ERC20/IBurnMintERC20.sol"; - -import {Create2} from "../../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Create2.sol"; import {IOwner} from "../../../interfaces/IOwner.sol"; + +import {Ownable2Step} from "../../../../shared/access/Ownable2Step.sol"; + +import {Router} from "../../../Router.sol"; import {RateLimiter} from "../../../libraries/RateLimiter.sol"; import {BurnFromMintTokenPool} from "../../../pools/BurnFromMintTokenPool.sol"; import {BurnMintTokenPool} from "../../../pools/BurnMintTokenPool.sol"; @@ -17,9 +18,26 @@ import {FactoryBurnMintERC20} from "../../../tokenAdminRegistry/TokenPoolFactory import {TokenPoolFactory} from "../../../tokenAdminRegistry/TokenPoolFactory/TokenPoolFactory.sol"; import {TokenPoolFactorySetup} from "./TokenPoolFactorySetup.t.sol"; +import {IERC20Metadata} from + "../../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol"; +import {Create2} from "../../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/Create2.sol"; + contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { using Create2 for bytes32; + uint8 private constant LOCAL_TOKEN_DECIMALS = 18; + uint8 private constant REMOTE_TOKEN_DECIMALS = 6; + + address internal s_burnMintOffRamp = makeAddr("burn_mint_offRamp"); + + function setUp() public override { + TokenPoolFactorySetup.setUp(); + + Router.OffRamp[] memory offRampUpdates = new Router.OffRamp[](1); + offRampUpdates[0] = Router.OffRamp({sourceChainSelector: DEST_CHAIN_SELECTOR, offRamp: s_burnMintOffRamp}); + s_sourceRouter.applyRampUpdates(new Router.OnRamp[](0), new Router.OffRamp[](0), offRampUpdates); + } + function test_createTokenPool_WithNoExistingTokenOnRemoteChain_Success() public { vm.startPrank(OWNER); @@ -29,7 +47,8 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { Create2.computeAddress(dynamicSalt, keccak256(s_tokenInitCode), address(s_tokenPoolFactory)); // Create the constructor params for the predicted pool - bytes memory poolCreationParams = abi.encode(predictedTokenAddress, new address[](0), s_rmnProxy, s_sourceRouter); + bytes memory poolCreationParams = + abi.encode(predictedTokenAddress, LOCAL_TOKEN_DECIMALS, new address[](0), s_rmnProxy, s_sourceRouter); // Predict the address of the pool before we make the tx by using the init code and the params bytes memory predictedPoolInitCode = abi.encodePacked(s_poolInitCode, poolCreationParams); @@ -38,7 +57,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { dynamicSalt.computeAddress(keccak256(predictedPoolInitCode), address(s_tokenPoolFactory)); (address tokenAddress, address poolAddress) = s_tokenPoolFactory.deployTokenAndTokenPool( - new TokenPoolFactory.RemoteTokenPoolInfo[](0), s_tokenInitCode, s_poolInitCode, FAKE_SALT + new TokenPoolFactory.RemoteTokenPoolInfo[](0), LOCAL_TOKEN_DECIMALS, s_tokenInitCode, s_poolInitCode, FAKE_SALT ); assertNotEq(address(0), tokenAddress, "Token Address should not be 0"); @@ -70,8 +89,9 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { newTokenAdminRegistry.addRegistryModule(address(newRegistryModule)); - TokenPoolFactory.RemoteChainConfig memory remoteChainConfig = - TokenPoolFactory.RemoteChainConfig(address(newTokenPoolFactory), address(s_destRouter), address(s_rmnProxy)); + TokenPoolFactory.RemoteChainConfig memory remoteChainConfig = TokenPoolFactory.RemoteChainConfig( + address(newTokenPoolFactory), address(s_destRouter), address(s_rmnProxy), LOCAL_TOKEN_DECIMALS + ); // Create an array of remote pools where nothing exists yet, but we want to predict the address for // the new pool and token on DEST_CHAIN_SELECTOR @@ -97,6 +117,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { // deployed token pool using the available getter functions (address tokenAddress, address poolAddress) = s_tokenPoolFactory.deployTokenAndTokenPool( remoteTokenPools, // No existing remote pools + LOCAL_TOKEN_DECIMALS, // 18 decimal token s_tokenInitCode, // Token Init Code s_poolInitCode, // Pool Init Code FAKE_SALT // Salt @@ -114,7 +135,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { // The predictedTokenAddress is NOT abi-encoded since the raw evm-address // is used in the constructor params bytes memory predictedPoolCreationParams = - abi.encode(predictedTokenAddress, new address[](0), s_rmnProxy, address(s_destRouter)); + abi.encode(predictedTokenAddress, LOCAL_TOKEN_DECIMALS, new address[](0), s_rmnProxy, address(s_destRouter)); // Take the init code and concat the destination params to it, the initCode shouldn't change bytes memory predictedPoolInitCode = abi.encodePacked(s_poolInitCode, predictedPoolCreationParams); @@ -126,7 +147,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { // Assert that the address set for the remote pool is the same as the predicted address assertEq( abi.encode(predictedPoolAddress), - TokenPool(poolAddress).getRemotePool(DEST_CHAIN_SELECTOR), + TokenPool(poolAddress).getRemotePools(DEST_CHAIN_SELECTOR)[0], "Pool Address should have been predicted" ); } @@ -134,11 +155,11 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { // On the new token pool factory, representing a destination chain, // deploy a new token and a new pool (address newTokenAddress, address newPoolAddress) = newTokenPoolFactory.deployTokenAndTokenPool( - new TokenPoolFactory.RemoteTokenPoolInfo[](0), s_tokenInitCode, s_poolInitCode, FAKE_SALT + new TokenPoolFactory.RemoteTokenPoolInfo[](0), LOCAL_TOKEN_DECIMALS, s_tokenInitCode, s_poolInitCode, FAKE_SALT ); assertEq( - TokenPool(poolAddress).getRemotePool(DEST_CHAIN_SELECTOR), + TokenPool(poolAddress).getRemotePools(DEST_CHAIN_SELECTOR)[0], abi.encode(newPoolAddress), "New Pool Address should have been deployed correctly" ); @@ -200,8 +221,9 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { newTokenAdminRegistry.addRegistryModule(address(newRegistryModule)); - TokenPoolFactory.RemoteChainConfig memory remoteChainConfig = - TokenPoolFactory.RemoteChainConfig(address(newTokenPoolFactory), address(s_destRouter), address(s_rmnProxy)); + TokenPoolFactory.RemoteChainConfig memory remoteChainConfig = TokenPoolFactory.RemoteChainConfig( + address(newTokenPoolFactory), address(s_destRouter), address(s_rmnProxy), LOCAL_TOKEN_DECIMALS + ); // Create an array of remote pools where nothing exists yet, but we want to predict the address for // the new pool and token on DEST_CHAIN_SELECTOR @@ -222,8 +244,9 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { // Since the remote chain information was provided, we should be able to get the information from the newly // deployed token pool using the available getter functions - (address tokenAddress, address poolAddress) = - s_tokenPoolFactory.deployTokenAndTokenPool(remoteTokenPools, s_tokenInitCode, s_poolInitCode, FAKE_SALT); + (address tokenAddress, address poolAddress) = s_tokenPoolFactory.deployTokenAndTokenPool( + remoteTokenPools, LOCAL_TOKEN_DECIMALS, s_tokenInitCode, s_poolInitCode, FAKE_SALT + ); assertEq(address(TokenPool(poolAddress).getToken()), tokenAddress, "Token Address should have been set locally"); @@ -238,7 +261,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { // The predictedTokenAddress is NOT abi-encoded since the raw evm-address // is used in the constructor params bytes memory predictedPoolCreationParams = - abi.encode(address(newRemoteToken), new address[](0), s_rmnProxy, address(s_destRouter)); + abi.encode(address(newRemoteToken), LOCAL_TOKEN_DECIMALS, new address[](0), s_rmnProxy, address(s_destRouter)); // Take the init code and concat the destination params to it, the initCode shouldn't change bytes memory predictedPoolInitCode = abi.encodePacked(s_poolInitCode, predictedPoolCreationParams); @@ -250,7 +273,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { // Assert that the address set for the remote pool is the same as the predicted address assertEq( abi.encode(predictedPoolAddress), - TokenPool(poolAddress).getRemotePool(DEST_CHAIN_SELECTOR), + TokenPool(poolAddress).getRemotePools(DEST_CHAIN_SELECTOR)[0], "Pool Address should have been predicted" ); @@ -258,6 +281,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { // deploy a new token and a new pool address newPoolAddress = newTokenPoolFactory.deployTokenPoolWithExistingToken( address(newRemoteToken), + LOCAL_TOKEN_DECIMALS, new TokenPoolFactory.RemoteTokenPoolInfo[](0), s_poolInitCode, FAKE_SALT, @@ -271,7 +295,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { ); assertEq( - TokenPool(poolAddress).getRemotePool(DEST_CHAIN_SELECTOR), + TokenPool(poolAddress).getRemotePools(DEST_CHAIN_SELECTOR)[0], abi.encode(newPoolAddress), "New Pool Address should have been deployed correctly" ); @@ -290,15 +314,16 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { DEST_CHAIN_SELECTOR, // remoteChainSelector RANDOM_POOL_ADDRESS, // remotePoolAddress type(BurnMintTokenPool).creationCode, // remotePoolInitCode - TokenPoolFactory.RemoteChainConfig(address(0), address(0), address(0)), // remoteChainConfig + TokenPoolFactory.RemoteChainConfig(address(0), address(0), address(0), 0), // remoteChainConfig TokenPoolFactory.PoolType.BURN_MINT, // poolType RANDOM_TOKEN_ADDRESS, // remoteTokenAddress "", // remoteTokenInitCode RateLimiter.Config(false, 0, 0) // rateLimiterConfig ); - (address tokenAddress, address poolAddress) = - s_tokenPoolFactory.deployTokenAndTokenPool(remoteTokenPools, s_tokenInitCode, s_poolInitCode, FAKE_SALT); + (address tokenAddress, address poolAddress) = s_tokenPoolFactory.deployTokenAndTokenPool( + remoteTokenPools, LOCAL_TOKEN_DECIMALS, s_tokenInitCode, s_poolInitCode, FAKE_SALT + ); assertNotEq(address(0), tokenAddress, "Token Address should not be 0"); assertNotEq(address(0), poolAddress, "Pool Address should not be 0"); @@ -314,7 +339,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { ); assertEq( - TokenPool(poolAddress).getRemotePool(DEST_CHAIN_SELECTOR), + TokenPool(poolAddress).getRemotePools(DEST_CHAIN_SELECTOR)[0], RANDOM_POOL_ADDRESS, "Remote Pool Address should have been set" ); @@ -339,8 +364,9 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { newTokenAdminRegistry.addRegistryModule(address(newRegistryModule)); - TokenPoolFactory.RemoteChainConfig memory remoteChainConfig = - TokenPoolFactory.RemoteChainConfig(address(newTokenPoolFactory), address(s_destRouter), address(s_rmnProxy)); + TokenPoolFactory.RemoteChainConfig memory remoteChainConfig = TokenPoolFactory.RemoteChainConfig( + address(newTokenPoolFactory), address(s_destRouter), address(s_rmnProxy), LOCAL_TOKEN_DECIMALS + ); FactoryBurnMintERC20 newLocalToken = new FactoryBurnMintERC20("TestToken", "TEST", 18, type(uint256).max, PREMINT_AMOUNT, OWNER); @@ -369,6 +395,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { // deployed token pool using the available getter functions address poolAddress = s_tokenPoolFactory.deployTokenPoolWithExistingToken( address(newLocalToken), + LOCAL_TOKEN_DECIMALS, remoteTokenPools, type(LockReleaseTokenPool).creationCode, FAKE_SALT, @@ -377,7 +404,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { // Check that the pool was correctly deployed on the local chain first - // Accept the ownership which was transfered + // Accept the ownership which was transferred Ownable2Step(poolAddress).acceptOwnership(); // Ensure that the remote Token was set to the one we predicted @@ -393,6 +420,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { // Deploy the Lock-Release Token Pool on the destination chain with the existing remote token (address newPoolAddress) = newTokenPoolFactory.deployTokenPoolWithExistingToken( address(newRemoteToken), + LOCAL_TOKEN_DECIMALS, new TokenPoolFactory.RemoteTokenPoolInfo[](0), // No existing remote pools type(LockReleaseTokenPool).creationCode, // Pool Init Code FAKE_SALT, // Salt @@ -400,7 +428,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { ); assertEq( - LockReleaseTokenPool(poolAddress).getRemotePool(DEST_CHAIN_SELECTOR), + LockReleaseTokenPool(poolAddress).getRemotePools(DEST_CHAIN_SELECTOR)[0], abi.encode(newPoolAddress), "New Pool Address should have been deployed correctly" ); @@ -431,15 +459,16 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { DEST_CHAIN_SELECTOR, // remoteChainSelector RANDOM_POOL_ADDRESS, // remotePoolAddress type(BurnFromMintTokenPool).creationCode, // remotePoolInitCode - TokenPoolFactory.RemoteChainConfig(address(0), address(0), address(0)), // remoteChainConfig + TokenPoolFactory.RemoteChainConfig(address(0), address(0), address(0), 0), // remoteChainConfig TokenPoolFactory.PoolType.BURN_MINT, // poolType RANDOM_TOKEN_ADDRESS, // remoteTokenAddress "", // remoteTokenInitCode RateLimiter.Config(false, 0, 0) // rateLimiterConfig ); - (address tokenAddress, address poolAddress) = - s_tokenPoolFactory.deployTokenAndTokenPool(remoteTokenPools, s_tokenInitCode, s_poolInitCode, FAKE_SALT); + (address tokenAddress, address poolAddress) = s_tokenPoolFactory.deployTokenAndTokenPool( + remoteTokenPools, LOCAL_TOKEN_DECIMALS, s_tokenInitCode, s_poolInitCode, FAKE_SALT + ); assertNotEq(address(0), tokenAddress, "Token Address should not be 0"); assertNotEq(address(0), poolAddress, "Pool Address should not be 0"); @@ -455,7 +484,7 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { ); assertEq( - TokenPool(poolAddress).getRemotePool(DEST_CHAIN_SELECTOR), + TokenPool(poolAddress).getRemotePools(DEST_CHAIN_SELECTOR)[0], RANDOM_POOL_ADDRESS, "Remote Pool Address should have been set" ); @@ -466,4 +495,112 @@ contract TokenPoolFactory_createTokenPool is TokenPoolFactorySetup { assertEq(IOwner(poolAddress).owner(), OWNER, "Token should be owned by the owner"); } + + function test_createTokenPool_RemoteTokenHasDifferentDecimals_Success() public { + vm.startPrank(OWNER); + bytes32 dynamicSalt = keccak256(abi.encodePacked(FAKE_SALT, OWNER)); + + // Deploy the "remote" token which has a different decimal value than the local token + FactoryBurnMintERC20 newRemoteToken = + new FactoryBurnMintERC20("TestToken", "TT", 6, type(uint256).max, PREMINT_AMOUNT, OWNER); + + // We have to create a new factory, registry module, and token admin registry to simulate the other chain + TokenAdminRegistry newTokenAdminRegistry = new TokenAdminRegistry(); + RegistryModuleOwnerCustom newRegistryModule = new RegistryModuleOwnerCustom(address(newTokenAdminRegistry)); + + // We want to deploy a new factory and Owner Module. + TokenPoolFactory newTokenPoolFactory = + new TokenPoolFactory(newTokenAdminRegistry, newRegistryModule, s_rmnProxy, address(s_destRouter)); + + newTokenAdminRegistry.addRegistryModule(address(newRegistryModule)); + + TokenPoolFactory.RemoteChainConfig memory remoteChainConfig = TokenPoolFactory.RemoteChainConfig( + address(newTokenPoolFactory), address(s_destRouter), address(s_rmnProxy), REMOTE_TOKEN_DECIMALS + ); + + // Create an array of remote pools where nothing exists yet, but we want to predict the address for + // the new pool and token on DEST_CHAIN_SELECTOR + TokenPoolFactory.RemoteTokenPoolInfo[] memory remoteTokenPools = new TokenPoolFactory.RemoteTokenPoolInfo[](1); + + // The only field that matters is DEST_CHAIN_SELECTOR because we dont want any existing token pool or token + // on the remote chain + remoteTokenPools[0] = TokenPoolFactory.RemoteTokenPoolInfo( + DEST_CHAIN_SELECTOR, // remoteChainSelector + "", // remotePoolAddress + type(BurnMintTokenPool).creationCode, // remotePoolInitCode + remoteChainConfig, // remoteChainConfig + TokenPoolFactory.PoolType.BURN_MINT, // poolType + abi.encode(address(newRemoteToken)), // remoteTokenAddress + s_tokenInitCode, // remoteTokenInitCode + RateLimiter.Config(false, 0, 0) // rateLimiterConfig + ); + + // Since the remote chain information was provided, we should be able to get the information from the newly + // deployed token pool using the available getter functions + (address tokenAddress, address poolAddress) = s_tokenPoolFactory.deployTokenAndTokenPool( + remoteTokenPools, LOCAL_TOKEN_DECIMALS, s_tokenInitCode, s_poolInitCode, FAKE_SALT + ); + + assertEq(address(TokenPool(poolAddress).getToken()), tokenAddress, "Token Address should have been set locally"); + + // Ensure that the remote Token was set to the one we predicted + assertEq( + abi.encode(address(newRemoteToken)), + TokenPool(poolAddress).getRemoteToken(DEST_CHAIN_SELECTOR), + "Token Address should have been predicted" + ); + + // Create the constructor params for the predicted pool + // The predictedTokenAddress is NOT abi-encoded since the raw evm-address + // is used in the constructor params + bytes memory predictedPoolCreationParams = + abi.encode(address(newRemoteToken), REMOTE_TOKEN_DECIMALS, new address[](0), s_rmnProxy, address(s_destRouter)); + + // Take the init code and concat the destination params to it, the initCode shouldn't change + bytes memory predictedPoolInitCode = abi.encodePacked(s_poolInitCode, predictedPoolCreationParams); + + // Predict the address of the pool on the DESTINATION chain + address predictedPoolAddress = + dynamicSalt.computeAddress(keccak256(predictedPoolInitCode), address(newTokenPoolFactory)); + + // Assert that the address set for the remote pool is the same as the predicted address + assertEq( + abi.encode(predictedPoolAddress), + TokenPool(poolAddress).getRemotePools(DEST_CHAIN_SELECTOR)[0], + "Pool Address should have been predicted" + ); + + // On the new token pool factory, representing a destination chain, + // deploy a new token and a new pool + address newPoolAddress = newTokenPoolFactory.deployTokenPoolWithExistingToken( + address(newRemoteToken), + REMOTE_TOKEN_DECIMALS, + new TokenPoolFactory.RemoteTokenPoolInfo[](0), + s_poolInitCode, + FAKE_SALT, + TokenPoolFactory.PoolType.BURN_MINT + ); + + assertEq( + abi.encode(newRemoteToken), + TokenPool(poolAddress).getRemoteToken(DEST_CHAIN_SELECTOR), + "Remote Token Address should have been set correctly" + ); + + assertEq( + TokenPool(poolAddress).getRemotePools(DEST_CHAIN_SELECTOR)[0], + abi.encode(newPoolAddress), + "New Pool Address should have been deployed correctly" + ); + + assertEq(TokenPool(poolAddress).getTokenDecimals(), LOCAL_TOKEN_DECIMALS, "Local token pool should use 18 decimals"); + + // Assert the local token has 18 decimals + assertEq(IERC20Metadata(tokenAddress).decimals(), LOCAL_TOKEN_DECIMALS, "Token Decimals should be 18"); + + // Check configs on the remote pool and remote token decimals + assertEq(TokenPool(newPoolAddress).getTokenDecimals(), REMOTE_TOKEN_DECIMALS, "Token Decimals should be 6"); + assertEq(address(TokenPool(newPoolAddress).getToken()), address(newRemoteToken), "Token Address should be set"); + assertEq(IERC20Metadata(newRemoteToken).decimals(), REMOTE_TOKEN_DECIMALS, "Token Decimals should be 6"); + } } diff --git a/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenPoolFactory/TokenPoolFactory.sol b/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenPoolFactory/TokenPoolFactory.sol index 4939b19b80c..94beff704a4 100644 --- a/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenPoolFactory/TokenPoolFactory.sol +++ b/contracts/src/v0.8/ccip/tokenAdminRegistry/TokenPoolFactory/TokenPoolFactory.sol @@ -37,8 +37,8 @@ contract TokenPoolFactory is ITypeAndVersion { // will be predicted bytes remotePoolInitCode; // Remote pool creation code if it needs to be deployed, without constructor params // appended to the end. - RemoteChainConfig remoteChainConfig; // The addresses of the remote RMNProxy, Router, and factory for determining - // the remote address + RemoteChainConfig remoteChainConfig; // The addresses of the remote RMNProxy, Router, factory, and token + // decimals which are needed for determining the remote address PoolType poolType; // The type of pool to deploy, either Burn/Mint or Lock/Release bytes remoteTokenAddress; // EVM address for remote token. If empty, the address will be predicted bytes remoteTokenInitCode; // The init code to be deployed on the remote chain and includes constructor params @@ -50,9 +50,10 @@ contract TokenPoolFactory is ITypeAndVersion { address remotePoolFactory; // The factory contract on the remote chain which will make the deployment address remoteRouter; // The router on the remote chain address remoteRMNProxy; // The RMNProxy contract on the remote chain + uint8 remoteTokenDecimals; // The number of decimals for the token on the remote chain } - string public constant typeAndVersion = "TokenPoolFactory 1.7.0-dev"; + string public constant typeAndVersion = "TokenPoolFactory 1.5.1"; ITokenAdminRegistry private immutable i_tokenAdminRegistry; RegistryModuleOwnerCustom private immutable i_registryModuleOwnerCustom; @@ -92,6 +93,8 @@ contract TokenPoolFactory is ITypeAndVersion { /// to the msg.sender, but must be accepted in a separate transaction due to 2-step ownership transfer. /// @param remoteTokenPools An array of remote token pools info to be used in the pool's applyChainUpdates function /// or to be predicted if the pool has not been deployed yet on the remote chain + /// @param localTokenDecimals The amount of decimals to be used in the new token. Since decimals() is not part of the + /// the ERC20 standard, and thus cannot be certain to exist, the amount must be supplied via user input. /// @param tokenInitCode The creation code for the token, which includes the constructor parameters already appended /// @param tokenPoolInitCode The creation code for the token pool, without the constructor parameters appended /// @param salt The salt to be used in the create2 deployment of the token and token pool to ensure a unique address @@ -99,6 +102,7 @@ contract TokenPoolFactory is ITypeAndVersion { /// @return pool The address of the token pool that was deployed function deployTokenAndTokenPool( RemoteTokenPoolInfo[] calldata remoteTokenPools, + uint8 localTokenDecimals, bytes memory tokenInitCode, bytes calldata tokenPoolInitCode, bytes32 salt @@ -111,7 +115,8 @@ contract TokenPoolFactory is ITypeAndVersion { address token = Create2.deploy(0, salt, tokenInitCode); // Deploy the token pool - address pool = _createTokenPool(token, remoteTokenPools, tokenPoolInitCode, salt, PoolType.BURN_MINT); + address pool = + _createTokenPool(token, localTokenDecimals, remoteTokenPools, tokenPoolInitCode, salt, PoolType.BURN_MINT); // Grant the mint and burn roles to the pool for the token FactoryBurnMintERC20(token).grantMintAndBurnRoles(pool); @@ -131,12 +136,15 @@ contract TokenPoolFactory is ITypeAndVersion { /// tokenAdminRegistry manually /// @dev since the token already exists, the owner must grant the mint and burn roles to the pool manually /// @param token The address of the existing token to be used in the token pool + /// @param localTokenDecimals The amount of decimals used in the existing token. Since decimals() is not part of the + /// the ERC20 standard, and thus cannot be certain to exist, the amount must be supplied via user input. /// @param remoteTokenPools An array of remote token pools info to be used in the pool's applyChainUpdates function /// @param tokenPoolInitCode The creation code for the token pool /// @param salt The salt to be used in the create2 deployment of the token pool /// @return poolAddress The address of the token pool that was deployed function deployTokenPoolWithExistingToken( address token, + uint8 localTokenDecimals, RemoteTokenPoolInfo[] calldata remoteTokenPools, bytes calldata tokenPoolInitCode, bytes32 salt, @@ -147,7 +155,7 @@ contract TokenPoolFactory is ITypeAndVersion { salt = keccak256(abi.encodePacked(salt, msg.sender)); // create the token pool and return the address - return _createTokenPool(token, remoteTokenPools, tokenPoolInitCode, salt, poolType); + return _createTokenPool(token, localTokenDecimals, remoteTokenPools, tokenPoolInitCode, salt, poolType); } // ================================================================ @@ -162,6 +170,7 @@ contract TokenPoolFactory is ITypeAndVersion { /// @return poolAddress The address of the token pool that was deployed function _createTokenPool( address token, + uint8 localTokenDecimals, RemoteTokenPoolInfo[] calldata remoteTokenPools, bytes calldata tokenPoolInitCode, bytes32 salt, @@ -203,10 +212,12 @@ contract TokenPoolFactory is ITypeAndVersion { abi.encode(salt.computeAddress(remotePoolInitcodeHash, remoteTokenPool.remoteChainConfig.remotePoolFactory)); } + bytes[] memory remotePoolAddresses = new bytes[](1); + remotePoolAddresses[0] = remoteTokenPool.remotePoolAddress; + chainUpdates[i] = TokenPool.ChainUpdate({ remoteChainSelector: remoteTokenPool.remoteChainSelector, - allowed: true, - remotePoolAddress: remoteTokenPool.remotePoolAddress, + remotePoolAddresses: remotePoolAddresses, remoteTokenAddress: remoteTokenPool.remoteTokenAddress, outboundRateLimiterConfig: remoteTokenPool.rateLimiterConfig, inboundRateLimiterConfig: remoteTokenPool.rateLimiterConfig @@ -216,18 +227,18 @@ contract TokenPoolFactory is ITypeAndVersion { // Construct the initArgs for the token pool using the immutable contracts for CCIP on the local chain bytes memory tokenPoolInitArgs; if (poolType == PoolType.BURN_MINT) { - tokenPoolInitArgs = abi.encode(token, new address[](0), i_rmnProxy, i_ccipRouter); + tokenPoolInitArgs = abi.encode(token, localTokenDecimals, new address[](0), i_rmnProxy, i_ccipRouter); } else if (poolType == PoolType.LOCK_RELEASE) { // Lock/Release pools have an additional boolean constructor parameter that must be accounted for, acceptLiquidity, // which is set to true by default in this case. Users wishing to set it to false must deploy the pool manually. - tokenPoolInitArgs = abi.encode(token, new address[](0), i_rmnProxy, true, i_ccipRouter); + tokenPoolInitArgs = abi.encode(token, localTokenDecimals, new address[](0), i_rmnProxy, true, i_ccipRouter); } // Construct the deployment code from the initCode and the initArgs and then deploy address poolAddress = Create2.deploy(0, salt, abi.encodePacked(tokenPoolInitCode, tokenPoolInitArgs)); // Apply the chain updates to the token pool - TokenPool(poolAddress).applyChainUpdates(chainUpdates); + TokenPool(poolAddress).applyChainUpdates(new uint64[](0), chainUpdates); // Begin the 2 step ownership transfer of the token pool to the msg.sender. IOwnable(poolAddress).transferOwnership(address(msg.sender)); // 2 step ownership transfer @@ -254,9 +265,13 @@ contract TokenPoolFactory is ITypeAndVersion { return keccak256( abi.encodePacked( initCode, - // constructor(address token, address[] allowlist, address rmnProxy, address router) + // constructor(address token, uint8 localTokenDecimals, address[] allowlist, address rmnProxy, address router) abi.encode( - remoteTokenAddress, new address[](0), remoteChainConfig.remoteRMNProxy, remoteChainConfig.remoteRouter + remoteTokenAddress, + remoteChainConfig.remoteTokenDecimals, + new address[](0), + remoteChainConfig.remoteRMNProxy, + remoteChainConfig.remoteRouter ) ) ); @@ -265,9 +280,14 @@ contract TokenPoolFactory is ITypeAndVersion { return keccak256( abi.encodePacked( initCode, - // constructor(address token, address[] allowList, address rmnProxy, bool acceptLiquidity, address router) + // constructor(address token, uint8 localTokenDecimals, address[] allowList, address rmnProxy, bool acceptLiquidity, address router) abi.encode( - remoteTokenAddress, new address[](0), remoteChainConfig.remoteRMNProxy, true, remoteChainConfig.remoteRouter + remoteTokenAddress, + remoteChainConfig.remoteTokenDecimals, + new address[](0), + remoteChainConfig.remoteRMNProxy, + true, + remoteChainConfig.remoteRouter ) ) ); diff --git a/contracts/src/v0.8/liquiditymanager/test/LiquidityManager.t.sol b/contracts/src/v0.8/liquiditymanager/test/LiquidityManager.t.sol index 73c9ba74455..088e36c4f0e 100644 --- a/contracts/src/v0.8/liquiditymanager/test/LiquidityManager.t.sol +++ b/contracts/src/v0.8/liquiditymanager/test/LiquidityManager.t.sol @@ -57,7 +57,14 @@ contract LiquidityManagerSetup is LiquidityManagerBaseTest { LiquidityManagerBaseTest.setUp(); s_bridgeAdapter = new MockL1BridgeAdapter(s_l1Token, false); - s_lockReleaseTokenPool = new LockReleaseTokenPool(s_l1Token, new address[](0), address(1), true, address(123)); + s_lockReleaseTokenPool = new LockReleaseTokenPool( + s_l1Token, + DEFAULT_TOKEN_DECIMALS, + new address[](0), + address(1), + true, + address(123) + ); s_liquidityManager = new LiquidityManagerHelper( s_l1Token, i_localChainSelector, @@ -71,6 +78,7 @@ contract LiquidityManagerSetup is LiquidityManagerBaseTest { s_wethBridgeAdapter = new MockL1BridgeAdapter(IERC20(address(s_l1Weth)), true); s_wethLockReleaseTokenPool = new LockReleaseTokenPool( IERC20(address(s_l1Weth)), + DEFAULT_TOKEN_DECIMALS, new address[](0), address(1), true, @@ -272,6 +280,7 @@ contract LiquidityManager_rebalanceLiquidity is LiquidityManagerSetup { MockL1BridgeAdapter remoteBridgeAdapter = new MockL1BridgeAdapter(s_l2Token, false); LockReleaseTokenPool remotePool = new LockReleaseTokenPool( s_l2Token, + DEFAULT_TOKEN_DECIMALS, new address[](0), address(1), true, @@ -401,6 +410,7 @@ contract LiquidityManager_rebalanceLiquidity is LiquidityManagerSetup { MockL1BridgeAdapter remoteBridgeAdapter = new MockL1BridgeAdapter(s_l2Token, false); LockReleaseTokenPool remotePool = new LockReleaseTokenPool( s_l2Token, + DEFAULT_TOKEN_DECIMALS, new address[](0), address(1), true, @@ -522,6 +532,7 @@ contract LiquidityManager_rebalanceLiquidity is LiquidityManagerSetup { MockL1BridgeAdapter remoteBridgeAdapter = new MockL1BridgeAdapter(IERC20(address(s_l2Weth)), true); LockReleaseTokenPool remotePool = new LockReleaseTokenPool( IERC20(address(s_l2Weth)), + DEFAULT_TOKEN_DECIMALS, new address[](0), address(1), true, @@ -817,6 +828,7 @@ contract LiquidityManager_setLocalLiquidityContainer is LiquidityManagerSetup { function test_setLocalLiquidityContainerSuccess() external { LockReleaseTokenPool newPool = new LockReleaseTokenPool( s_l1Token, + DEFAULT_TOKEN_DECIMALS, new address[](0), address(1), true, diff --git a/contracts/src/v0.8/liquiditymanager/test/LiquidityManagerBaseTest.t.sol b/contracts/src/v0.8/liquiditymanager/test/LiquidityManagerBaseTest.t.sol index 128a03f255a..48492699473 100644 --- a/contracts/src/v0.8/liquiditymanager/test/LiquidityManagerBaseTest.t.sol +++ b/contracts/src/v0.8/liquiditymanager/test/LiquidityManagerBaseTest.t.sol @@ -25,6 +25,7 @@ contract LiquidityManagerBaseTest is Test { address internal constant FINANCE = address(0x00000fffffffffffffffffffff); address internal constant OWNER = address(0x00000078772732723782873283); address internal constant STRANGER = address(0x00000999999911111111222222); + uint8 internal constant DEFAULT_TOKEN_DECIMALS = 18; function setUp() public virtual { s_l1Token = new ERC20("l1", "L1"); diff --git a/contracts/src/v0.8/vendor/forge-std/src/Vm.sol b/contracts/src/v0.8/vendor/forge-std/src/Vm.sol index 591508c097a..0f2dc50ff70 100644 --- a/contracts/src/v0.8/vendor/forge-std/src/Vm.sol +++ b/contracts/src/v0.8/vendor/forge-std/src/Vm.sol @@ -243,6 +243,27 @@ interface VmSafe { uint64 gasRemaining; } + /// The result of the `stopDebugTraceRecording` call + struct DebugStep { + // The stack before executing the step of the run. + // stack\[0\] represents the top of the stack. + // and only stack data relevant to the opcode execution is contained. + uint256[] stack; + // The memory input data before executing the step of the run. + // only input data relevant to the opcode execution is contained. + // e.g. for MLOAD, it will have memory\[offset:offset+32\] copied here. + // the offset value can be get by the stack data. + bytes memoryInput; + // The opcode that was accessed. + uint8 opcode; + // The call depth of the step. + uint64 depth; + // Whether the call end up with out of gas error. + bool isOutOfGas; + // The contract address where the opcode is running + address contractAddr; + } + // ======== Crypto ======== /// Derives a private key from the name, labels the account with that name, and returns the wallet. @@ -285,6 +306,23 @@ interface VmSafe { /// Adds a private key to the local forge wallet and returns the address. function rememberKey(uint256 privateKey) external returns (address keyAddr); + /// Derive a set number of wallets from a mnemonic at the derivation path `m/44'/60'/0'/0/{0..count}`. + /// + /// The respective private keys are saved to the local forge wallet for later use and their addresses are returned. + function rememberKeys(string calldata mnemonic, string calldata derivationPath, uint32 count) + external + returns (address[] memory keyAddrs); + + /// Derive a set number of wallets from a mnemonic in the specified language at the derivation path `m/44'/60'/0'/0/{0..count}`. + /// + /// The respective private keys are saved to the local forge wallet for later use and their addresses are returned. + function rememberKeys( + string calldata mnemonic, + string calldata derivationPath, + string calldata language, + uint32 count + ) external returns (address[] memory keyAddrs); + /// Signs data with a `Wallet`. /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the /// signature's `s` value, and the recovery id `v` in a single bytes32. @@ -544,7 +582,7 @@ interface VmSafe { /// Gets all the recorded logs. function getRecordedLogs() external returns (Log[] memory logs); - /// Gets the gas used in the last call. + /// Gets the gas used in the last call from the callee perspective. function lastCallGas() external view returns (Gas memory gas); /// Loads a storage slot from an address. @@ -573,6 +611,9 @@ interface VmSafe { external returns (bytes memory data); + /// Records the debug trace during the run. + function startDebugTraceRecording() external; + /// Starts recording all map SSTOREs for later retrieval. function startMappingRecording() external; @@ -580,6 +621,9 @@ interface VmSafe { /// along with the context of the calls function startStateDiffRecording() external; + /// Stop debug trace recording and returns the recorded debug trace. + function stopAndReturnDebugTraceRecording() external returns (DebugStep[] memory step); + /// Returns an ordered array of all account accesses from a `vm.startStateDiffRecording` session. function stopAndReturnStateDiff() external returns (AccountAccess[] memory accountAccesses); @@ -931,6 +975,9 @@ interface VmSafe { /// provided as the sender that can later be signed and sent onchain. function broadcast(uint256 privateKey) external; + /// Returns addresses of available unlocked wallets in the script environment. + function getScriptWallets() external returns (address[] memory wallets); + /// Has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain. /// Broadcasting address is determined by checking the following in order: /// 1. If `--sender` argument was provided, that address is used. @@ -949,6 +996,9 @@ interface VmSafe { /// Stops collecting onchain transactions. function stopBroadcast() external; + /// Returns addresses of available unlocked wallets in the script environment. + function getWallets() external returns (address[] memory wallets); + // ======== String ======== /// Returns the index of the first occurrence of a `key` in an `input` string. @@ -1447,10 +1497,10 @@ interface VmSafe { function assumeNoRevert() external pure; /// Writes a breakpoint to jump to in the debugger. - function breakpoint(string calldata char) external; + function breakpoint(string calldata char) external pure; /// Writes a conditional breakpoint to jump to in the debugger. - function breakpoint(string calldata char, bool value) external; + function breakpoint(string calldata char, bool value) external pure; /// Returns the Foundry version. /// Format: ++ @@ -1592,16 +1642,22 @@ interface VmSafe { /// Returns a random `address`. function randomAddress() external returns (address); - /// Returns an random `bool`. + /// Returns a random `bool`. function randomBool() external view returns (bool); - /// Returns an random byte array value of the given length. + /// Returns a random byte array value of the given length. function randomBytes(uint256 len) external view returns (bytes memory); - /// Returns an random `int256` value. + /// Returns a random fixed-size byte array of length 4. + function randomBytes4() external view returns (bytes4); + + /// Returns a random fixed-size byte array of length 8. + function randomBytes8() external view returns (bytes8); + + /// Returns a random `int256` value. function randomInt() external view returns (int256); - /// Returns an random `int256` value of given bits. + /// Returns a random `int256` value of given bits. function randomInt(uint256 bits) external view returns (int256); /// Returns a random uint256 value. @@ -1610,7 +1666,7 @@ interface VmSafe { /// Returns random uint256 value between the provided range (=min..=max). function randomUint(uint256 min, uint256 max) external returns (uint256); - /// Returns an random `uint256` value of given bits. + /// Returns a random `uint256` value of given bits. function randomUint(uint256 bits) external view returns (uint256); /// Unpauses collection of call traces. @@ -1657,6 +1713,9 @@ interface Vm is VmSafe { /// Clears all mocked calls. function clearMockedCalls() external; + /// Clones a source account code, state, balance and nonce to a target account and updates in-memory EVM state. + function cloneAccount(address source, address target) external; + /// Sets `block.coinbase`. function coinbase(address newCoinbase) external; @@ -1687,10 +1746,10 @@ interface Vm is VmSafe { /// Takes the snapshot ID to delete. /// Returns `true` if the snapshot was successfully deleted. /// Returns `false` if the snapshot does not exist. - function deleteSnapshot(uint256 snapshotId) external returns (bool success); + function deleteStateSnapshot(uint256 snapshotId) external returns (bool success); /// Removes _all_ snapshots previously created by `snapshot`. - function deleteSnapshots() external; + function deleteStateSnapshots() external; /// Sets `block.difficulty`. /// Not available on EVM versions from Paris onwards. Use `prevrandao` instead. @@ -1714,7 +1773,7 @@ interface Vm is VmSafe { /// Returns true if the account is marked as persistent. function isPersistent(address account) external view returns (bool persistent); - /// Load a genesis JSON file's `allocs` into the in-memory revm state. + /// Load a genesis JSON file's `allocs` into the in-memory EVM state. function loadAllocs(string calldata pathToAllocsJson) external; /// Marks that the account(s) should use persistent storage across fork swaps in a multifork setup @@ -1747,6 +1806,12 @@ interface Vm is VmSafe { /// Calldata match takes precedence over `msg.value` in case of ambiguity. function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external; + /// Mocks multiple calls to an address, returning specified data for each call. + function mockCalls(address callee, bytes calldata data, bytes[] calldata returnData) external; + + /// Mocks multiple calls to an address with a specific `msg.value`, returning specified data for each call. + function mockCalls(address callee, uint256 msgValue, bytes calldata data, bytes[] calldata returnData) external; + /// Whenever a call is made to `callee` with calldata `data`, this cheatcode instead calls /// `target` with the same calldata. This functionality is similar to a delegate call made to /// `target` contract from `callee`. @@ -1781,14 +1846,14 @@ interface Vm is VmSafe { /// Takes the snapshot ID to revert to. /// Returns `true` if the snapshot was successfully reverted. /// Returns `false` if the snapshot does not exist. - /// **Note:** This does not automatically delete the snapshot. To delete the snapshot use `deleteSnapshot`. - function revertTo(uint256 snapshotId) external returns (bool success); + /// **Note:** This does not automatically delete the snapshot. To delete the snapshot use `deleteStateSnapshot`. + function revertToState(uint256 snapshotId) external returns (bool success); /// Revert the state of the EVM to a previous snapshot and automatically deletes the snapshots /// Takes the snapshot ID to revert to. /// Returns `true` if the snapshot was successfully reverted and deleted. /// Returns `false` if the snapshot does not exist. - function revertToAndDelete(uint256 snapshotId) external returns (bool success); + function revertToStateAndDelete(uint256 snapshotId) external returns (bool success); /// Revokes persistent status from the address, previously added via `makePersistent`. function revokePersistent(address account) external; @@ -1826,10 +1891,23 @@ interface Vm is VmSafe { /// Sets the nonce of an account to an arbitrary value. function setNonceUnsafe(address account, uint64 newNonce) external; + /// Snapshot capture the gas usage of the last call by name from the callee perspective. + function snapshotGasLastCall(string calldata name) external returns (uint256 gasUsed); + + /// Snapshot capture the gas usage of the last call by name in a group from the callee perspective. + function snapshotGasLastCall(string calldata group, string calldata name) external returns (uint256 gasUsed); + /// Snapshot the current state of the evm. /// Returns the ID of the snapshot that was created. - /// To revert a snapshot use `revertTo`. - function snapshot() external returns (uint256 snapshotId); + /// To revert a snapshot use `revertToState`. + function snapshotState() external returns (uint256 snapshotId); + + /// Snapshot capture an arbitrary numerical value by name. + /// The group name is derived from the contract name. + function snapshotValue(string calldata name, uint256 value) external; + + /// Snapshot capture an arbitrary numerical value by name in a group. + function snapshotValue(string calldata group, string calldata name, uint256 value) external; /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called. function startPrank(address msgSender) external; @@ -1837,9 +1915,26 @@ interface Vm is VmSafe { /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called, and the `tx.origin` to be the second input. function startPrank(address msgSender, address txOrigin) external; + /// Start a snapshot capture of the current gas usage by name. + /// The group name is derived from the contract name. + function startSnapshotGas(string calldata name) external; + + /// Start a snapshot capture of the current gas usage by name in a group. + function startSnapshotGas(string calldata group, string calldata name) external; + /// Resets subsequent calls' `msg.sender` to be `address(this)`. function stopPrank() external; + /// Stop the snapshot capture of the current gas by latest snapshot name, capturing the gas used since the start. + function stopSnapshotGas() external returns (uint256 gasUsed); + + /// Stop the snapshot capture of the current gas usage by name, capturing the gas used since the start. + /// The group name is derived from the contract name. + function stopSnapshotGas(string calldata name) external returns (uint256 gasUsed); + + /// Stop the snapshot capture of the current gas usage by name in a group, capturing the gas used since the start. + function stopSnapshotGas(string calldata group, string calldata name) external returns (uint256 gasUsed); + /// Stores a value to an address' storage slot. function store(address target, bytes32 slot, bytes32 value) external; @@ -1855,6 +1950,21 @@ interface Vm is VmSafe { /// Sets `block.timestamp`. function warp(uint256 newTimestamp) external; + /// `deleteSnapshot` is being deprecated in favor of `deleteStateSnapshot`. It will be removed in future versions. + function deleteSnapshot(uint256 snapshotId) external returns (bool success); + + /// `deleteSnapshots` is being deprecated in favor of `deleteStateSnapshots`. It will be removed in future versions. + function deleteSnapshots() external; + + /// `revertToAndDelete` is being deprecated in favor of `revertToStateAndDelete`. It will be removed in future versions. + function revertToAndDelete(uint256 snapshotId) external returns (bool success); + + /// `revertTo` is being deprecated in favor of `revertToState`. It will be removed in future versions. + function revertTo(uint256 snapshotId) external returns (bool success); + + /// `snapshot` is being deprecated in favor of `snapshotState`. It will be removed in future versions. + function snapshot() external returns (uint256 snapshotId); + // ======== Testing ======== /// Expect a call to an address with the specified `msg.value` and calldata, and a *minimum* amount of gas. diff --git a/contracts/src/v0.8/workflow/dev/WorkflowRegistry.sol b/contracts/src/v0.8/workflow/dev/WorkflowRegistry.sol index b0b6a120f86..0e6ae3450ac 100644 --- a/contracts/src/v0.8/workflow/dev/WorkflowRegistry.sol +++ b/contracts/src/v0.8/workflow/dev/WorkflowRegistry.sol @@ -83,8 +83,8 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { bytes32 indexed workflowID, address indexed workflowOwner, uint32 indexed donID, string workflowName ); event WorkflowForceUpdateSecretsRequestedV1(address indexed owner, bytes32 secretsURLHash, string workflowName); - event RegistryLockedV1(address indexed lockedBy); - event RegistryUnlockedV1(address indexed unlockedBy); + event RegistryLockedV1(address lockedBy); + event RegistryUnlockedV1(address unlockedBy); error AddressNotAuthorized(address caller); error CallerIsNotWorkflowOwner(address caller); @@ -306,7 +306,7 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { if (!sameSecretsURL) { // Remove the old secrets hash if secretsURL is not empty if (bytes(workflow.secretsURL).length > 0) { - // Using keccak256 instead of _computeOwnerAndStringFieldHashKey as currentSecretsURL is memory + // Using keccak256 instead of computeHashKey as currentSecretsURL is memory bytes32 oldSecretsHash = keccak256(abi.encodePacked(msg.sender, workflow.secretsURL)); s_secretsHashToWorkflows[oldSecretsHash].remove(workflowKey); } @@ -378,34 +378,31 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { function deleteWorkflow( bytes32 workflowKey ) external registryNotLocked { - address sender = msg.sender; - // Retrieve workflow metadata from storage - WorkflowMetadata storage workflow = _getWorkflowFromStorage(sender, workflowKey); - uint32 donID = workflow.donID; + WorkflowMetadata storage workflow = _getWorkflowFromStorage(msg.sender, workflowKey); // Only checking access for the caller instead of using _validatePermissions so that even if the DON was removed from the // allowed list, the workflow can still be deleted. - if (!s_authorizedAddresses.contains(sender)) { - revert AddressNotAuthorized(sender); + if (!s_authorizedAddresses.contains(msg.sender)) { + revert AddressNotAuthorized(msg.sender); } // Remove the workflow from the owner and DON mappings - s_ownerWorkflowKeys[sender].remove(workflowKey); - s_donWorkflowKeys[donID].remove(workflowKey); + s_ownerWorkflowKeys[msg.sender].remove(workflowKey); + s_donWorkflowKeys[workflow.donID].remove(workflowKey); // Remove the workflow from the secrets hash set if secretsURL is not empty if (bytes(workflow.secretsURL).length > 0) { - // Using keccak256 instead of _computeOwnerAndStringFieldHashKey as secretsURL is storage ref - bytes32 secretsHash = keccak256(abi.encodePacked(sender, workflow.secretsURL)); + // Using keccak256 instead of computeHashKey as secretsURL is storage ref + bytes32 secretsHash = keccak256(abi.encodePacked(msg.sender, workflow.secretsURL)); s_secretsHashToWorkflows[secretsHash].remove(workflowKey); } + // Emit an event indicating the workflow has been deleted. We need to do this before deleting the workflow from storage. + emit WorkflowDeletedV1(workflow.workflowID, msg.sender, workflow.donID, workflow.workflowName); + // Delete the workflow metadata from storage delete s_workflows[workflowKey]; - - // Emit an event indicating the workflow has been deleted - emit WorkflowDeletedV1(workflow.workflowID, sender, donID, workflow.workflowName); } /// @notice Requests a force update for workflows that share the same secrets URL. @@ -430,10 +427,8 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { function requestForceUpdateSecrets( string calldata secretsURL ) external registryNotLocked { - address sender = msg.sender; - // Use secretsURL and sender hash key to get the mapping key - bytes32 secretsHash = computeHashKey(sender, secretsURL); + bytes32 secretsHash = computeHashKey(msg.sender, secretsURL); // Retrieve all workflow keys associated with the given secrets hash EnumerableSet.Bytes32Set storage workflowKeys = s_secretsHashToWorkflows[secretsHash]; @@ -449,8 +444,8 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { bytes32 workflowKey = workflowKeys.at(i); WorkflowMetadata storage workflow = s_workflows[workflowKey]; - if (s_allowedDONs.contains(workflow.donID) && s_authorizedAddresses.contains(sender)) { - emit WorkflowForceUpdateSecretsRequestedV1(sender, secretsHash, workflow.workflowName); + if (s_allowedDONs.contains(workflow.donID) && s_authorizedAddresses.contains(msg.sender)) { + emit WorkflowForceUpdateSecretsRequestedV1(msg.sender, secretsHash, workflow.workflowName); } } } @@ -472,10 +467,8 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { /// @param workflowKey The unique identifier for the workflow. /// @param newStatus The new status to set for the workflow (either `Paused` or `Active`). function _updateWorkflowStatus(bytes32 workflowKey, WorkflowStatus newStatus) internal { - address sender = msg.sender; - // Retrieve workflow metadata once - WorkflowMetadata storage workflow = _getWorkflowFromStorage(sender, workflowKey); + WorkflowMetadata storage workflow = _getWorkflowFromStorage(msg.sender, workflowKey); uint32 donID = workflow.donID; // Avoid unnecessary storage writes if already in the desired status @@ -485,7 +478,7 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { // Check if the DON ID is allowed when activating a workflow if (newStatus == WorkflowStatus.ACTIVE) { - _validatePermissions(donID, sender); + _validatePermissions(donID, msg.sender); } // Update the workflow status @@ -493,9 +486,9 @@ contract WorkflowRegistry is Ownable2StepMsgSender, ITypeAndVersion { // Emit the appropriate event based on newStatus if (newStatus == WorkflowStatus.PAUSED) { - emit WorkflowPausedV1(workflow.workflowID, sender, donID, workflow.workflowName); + emit WorkflowPausedV1(workflow.workflowID, msg.sender, donID, workflow.workflowName); } else if (newStatus == WorkflowStatus.ACTIVE) { - emit WorkflowActivatedV1(workflow.workflowID, sender, donID, workflow.workflowName); + emit WorkflowActivatedV1(workflow.workflowID, msg.sender, donID, workflow.workflowName); } } diff --git a/contracts/src/v0.8/workflow/dev/WorkflowRegistryManager.sol b/contracts/src/v0.8/workflow/dev/WorkflowRegistryManager.sol index 8c760707ee2..818d4a1a8ae 100644 --- a/contracts/src/v0.8/workflow/dev/WorkflowRegistryManager.sol +++ b/contracts/src/v0.8/workflow/dev/WorkflowRegistryManager.sol @@ -26,6 +26,10 @@ contract WorkflowRegistryManager is Ownable2StepMsgSender, ITypeAndVersion { /// indexing strategy to avoid off-by-one errors. mapping(uint32 versionNumber => Version versionInfo) private s_versions; + /// @notice Maps a combination of address and chain ID to the version number. + /// @dev This mapping allows for lookup of the version number for a given address and chain ID. + mapping(bytes32 => uint32) private s_versionNumberByAddressAndChainID; + /// @notice The version number of the currently active WorkflowRegistry. /// @dev Initialized to 0 to indicate no active version. Updated when a version is activated. uint32 private s_activeVersionNumber = 0; @@ -34,21 +38,18 @@ contract WorkflowRegistryManager is Ownable2StepMsgSender, ITypeAndVersion { /// @dev Incremented each time a new version is added. Useful for iterating over all registered versions. uint32 private s_latestVersionNumber = 0; - /// @notice Maps a combination of address and chain ID to the version number. - /// @dev This mapping allows for lookup of the version number for a given address and chain ID. - mapping(bytes32 => uint32) private s_versionNumberByAddressAndChainID; - // Errors error InvalidContractAddress(address invalidAddress); error InvalidContractType(address invalidAddress); error NoActiveVersionAvailable(); error NoVersionsRegistered(); error VersionNotRegistered(uint32 versionNumber); + error VersionAlreadyActive(uint32 versionNumber); // Events event VersionAdded(address indexed contractAddress, uint64 chainID, uint32 deployedAt, uint32 version); - event VersionActivated(address indexed contractAddress, uint64 chainID, uint32 indexed version); - event VersionDeactivated(address indexed contractAddress, uint64 chainID, uint32 indexed version); + event VersionActivated(address indexed contractAddress, uint64 chainID, uint32 version); + event VersionDeactivated(address indexed contractAddress, uint64 chainID, uint32 version); // ================================================================ // | Manage Versions | @@ -110,6 +111,11 @@ contract WorkflowRegistryManager is Ownable2StepMsgSender, ITypeAndVersion { // Cache the current active version number to reduce storage reads uint32 currentActiveVersionNumber = s_activeVersionNumber; + // Check that the version number is not the same as the current active version number + if (currentActiveVersionNumber == versionNumber) { + revert VersionAlreadyActive(versionNumber); + } + // Emit deactivation event if there is an active version if (currentActiveVersionNumber != 0) { Version memory currentActive = s_versions[currentActiveVersionNumber]; @@ -178,7 +184,10 @@ contract WorkflowRegistryManager is Ownable2StepMsgSender, ITypeAndVersion { /// @param contractAddress The address of the WorkflowRegistry contract. /// @param chainID The chain ID of the network where the WorkflowRegistry is deployed. /// @return versionNumber The version number associated with the given contract address and chain ID. - function getVersionNumber(address contractAddress, uint64 chainID) external view returns (uint32 versionNumber) { + function getVersionNumberByContractAddressAndChainID( + address contractAddress, + uint64 chainID + ) external view returns (uint32 versionNumber) { _validateContractAddress(contractAddress); bytes32 key = keccak256(abi.encodePacked(contractAddress, chainID)); @@ -201,10 +210,10 @@ contract WorkflowRegistryManager is Ownable2StepMsgSender, ITypeAndVersion { /// @notice Retrieves the details of the latest registered WorkflowRegistry version. /// @return A `Version` struct containing the details of the latest version. - /// @custom:throws NoActiveVersionAvailable if no versions have been registered. + /// @custom:throws NoVersionsRegistered if no versions have been registered. function getLatestVersion() external view returns (Version memory) { uint32 latestVersionNumber = s_latestVersionNumber; - if (latestVersionNumber == 0) revert NoActiveVersionAvailable(); + if (latestVersionNumber == 0) revert NoVersionsRegistered(); return s_versions[latestVersionNumber]; } @@ -246,6 +255,9 @@ contract WorkflowRegistryManager is Ownable2StepMsgSender, ITypeAndVersion { } } + /// @dev Validates that a given contract address is non-zero and contains code. + /// @param _addr The address of the contract to validate. + /// @custom:throws InvalidContractAddress if the address is zero or contains no code. function _validateContractAddress( address _addr ) internal view { diff --git a/contracts/src/v0.8/workflow/mocks/MockContract.sol b/contracts/src/v0.8/workflow/mocks/MockContract.sol new file mode 100644 index 00000000000..667e05daeae --- /dev/null +++ b/contracts/src/v0.8/workflow/mocks/MockContract.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +contract MockContract {} diff --git a/contracts/src/v0.8/workflow/mocks/MockWorkflowRegistryContract.sol b/contracts/src/v0.8/workflow/mocks/MockWorkflowRegistryContract.sol new file mode 100644 index 00000000000..8a8c9c7de08 --- /dev/null +++ b/contracts/src/v0.8/workflow/mocks/MockWorkflowRegistryContract.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; + +contract MockWorkflowRegistryContract is ITypeAndVersion { + string public constant override typeAndVersion = "MockWorkflowRegistryContract 1.0.0"; +} diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.activateWorkflow.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.activateWorkflow.t.sol index 47858774e0d..3b2bc854325 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.activateWorkflow.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.activateWorkflow.t.sol @@ -104,6 +104,12 @@ contract WorkflowRegistry_activateWorkflow is WorkflowRegistrySetup { s_validSecretsURL ); + // It should emit {WorkflowActivatedV1} when the workflow is activated. + vm.expectEmit(); + emit WorkflowRegistry.WorkflowActivatedV1( + s_validWorkflowID, s_authorizedAddress, s_allowedDonID, s_validWorkflowName + ); + // Activate the workflow. vm.prank(s_authorizedAddress); s_registry.activateWorkflow(s_validWorkflowKey); diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.activateWorkflow.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.activateWorkflow.tree index 3d71d5844db..4765b5abbe5 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.activateWorkflow.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.activateWorkflow.tree @@ -5,13 +5,13 @@ WorkflowRegistry.activateWorkflow ├── when the caller is not the workflow owner │ └── it should revert └── when the caller is the workflow owner - ├── when the workflow is already paused + ├── when the workflow is already active │ └── it should revert └── when the workflow is paused ├── when the donID is not allowed │ └── it should revert └── when the donID is allowed - └── when the caller is not an authorized address + ├── when the caller is not an authorized address │ └── it should revert └── when the caller is an authorized address - └── it should activate the workflow + └── it should activate the workflow and emit {WorkflowActivatedV1} diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.deleteWorkflow.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.deleteWorkflow.t.sol index bbc4c7bb33a..974a3590f03 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.deleteWorkflow.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.deleteWorkflow.t.sol @@ -57,6 +57,10 @@ contract WorkflowRegistry_deleteWorkflow is WorkflowRegistrySetup { s_registry.getWorkflowMetadata(s_authorizedAddress, s_validWorkflowName); assertEq(workflow.workflowName, s_validWorkflowName); + // It should emit {WorkflowDeletedV1} when the workflow is deleted. + vm.expectEmit(); + emit WorkflowRegistry.WorkflowDeletedV1(s_validWorkflowID, s_authorizedAddress, s_allowedDonID, s_validWorkflowName); + // Delete the workflow. vm.prank(s_authorizedAddress); s_registry.deleteWorkflow(s_validWorkflowKey); @@ -79,6 +83,10 @@ contract WorkflowRegistry_deleteWorkflow is WorkflowRegistrySetup { // Remove the DON from the allowed DONs list. _removeDONFromAllowedDONs(s_allowedDonID); + // It should emit {WorkflowDeletedV1} when the workflow is deleted. + vm.expectEmit(); + emit WorkflowRegistry.WorkflowDeletedV1(s_validWorkflowID, s_authorizedAddress, s_allowedDonID, s_validWorkflowName); + // Delete the workflow. vm.prank(s_authorizedAddress); s_registry.deleteWorkflow(s_validWorkflowKey); diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.deleteWorkflow.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.deleteWorkflow.tree index 510906137b9..4f6fd289b18 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.deleteWorkflow.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.deleteWorkflow.tree @@ -8,5 +8,5 @@ WorkflowRegistry.deleteWorkflow ├── when the caller is not an authorized address │ └── it should revert └── when the caller is an authorized address - ├── it should delete the workflow if the donID is not allowed - └── it should delete the workflow if the donID is allowed + ├── it should delete the workflow if the donID is not allowed and emit {WorkflowDeletedV1} + └── it should delete the workflow if the donID is allowed and emit {WorkflowDeletedV1} diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAllowedDONs.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAllowedDONs.t.sol index d6c76d369c0..7fdb2462f39 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAllowedDONs.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAllowedDONs.t.sol @@ -31,4 +31,16 @@ contract WorkflowRegistry_getAllAllowedDONs is WorkflowRegistrySetup { assertEq(allowedDONs[0], s_allowedDonID); assertEq(allowedDONs[1], allowedDonID2); } + + function test_WhenTheRegistryIsLocked() external { + // Lock the registry + vm.prank(s_owner); + s_registry.lockRegistry(); + + // It should behave the same as when the registry is not locked + vm.prank(s_stranger); + uint32[] memory allowedDONs = s_registry.getAllAllowedDONs(); + assertEq(allowedDONs.length, 1); + assertEq(allowedDONs[0], s_allowedDonID); + } } diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAllowedDONs.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAllowedDONs.tree index 5e0d4e8d550..a6b649a8c98 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAllowedDONs.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAllowedDONs.tree @@ -3,5 +3,7 @@ WorkflowRegistry.getAllAllowedDONs │ └── it should return an empty array ├── when there is a single allowed DON │ └── it should return an array with one element -└── when there are multiple allowed DONs - └── it should return an array with all the allowed DONs +├── when there are multiple allowed DONs +│ └── it should return an array with all the allowed DONs +└── when the registry is locked + └── it should behave the same as when the registry is not locked diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAuthorizedAddresses.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAuthorizedAddresses.t.sol index 0b47da3938c..edaef531f77 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAuthorizedAddresses.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAuthorizedAddresses.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; import {WorkflowRegistrySetup} from "./WorkflowRegistrySetup.t.sol"; -contract WorkflowRegistrygetAllAuthorizedAddresses is WorkflowRegistrySetup { +contract WorkflowRegistry_getAllAuthorizedAddresses is WorkflowRegistrySetup { function test_WhenTheSetOfAuthorizedAddressesIsEmpty() external { // Remove the authorized address added in the setup _removeAddressFromAuthorizedAddresses(s_authorizedAddress); @@ -28,4 +28,16 @@ contract WorkflowRegistrygetAllAuthorizedAddresses is WorkflowRegistrySetup { assertEq(authorizedAddresses[0], s_authorizedAddress); assertEq(authorizedAddresses[1], s_unauthorizedAddress); } + + function test_WhenTheRegistryIsLocked() external { + // Lock the registry + vm.prank(s_owner); + s_registry.lockRegistry(); + + // It should behave the same as when the registry is not locked + vm.prank(s_stranger); + address[] memory authorizedAddresses = s_registry.getAllAuthorizedAddresses(); + assertEq(authorizedAddresses.length, 1); + assertEq(authorizedAddresses[0], s_authorizedAddress); + } } diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAuthorizedAddresses.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAuthorizedAddresses.tree index 86821d2f83e..d4908dbd7ec 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAuthorizedAddresses.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getAllAuthorizedAddresses.tree @@ -3,5 +3,7 @@ WorkflowRegistry.getAllAuthorizedAddresses │ └── it should return an empty array ├── when there is a single authorized address │ └── it should return an array with one element -└── when there are multiple authorized addresses - └── it should return an array with all the authorized addresses +├── when there are multiple authorized addresses +│ └── it should return an array with all the authorized addresses +└── when the registry is locked + └── it should behave the same as when the registry is not locked diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadata.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadata.t.sol index 3cd092676be..5bc78feb0f2 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadata.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadata.t.sol @@ -22,4 +22,24 @@ contract WorkflowRegistry_getWorkflowMetadata is WorkflowRegistrySetup { vm.expectRevert(WorkflowRegistry.WorkflowDoesNotExist.selector); s_registry.getWorkflowMetadata(s_authorizedAddress, "RandomWorkflowName"); } + + function test_WhenTheRegistryIsLocked() external { + // Register a workflow + _registerValidWorkflow(); + + // Lock the registry + vm.prank(s_owner); + s_registry.lockRegistry(); + + // It should behave the same as when the registry is not locked + vm.prank(s_stranger); + WorkflowRegistry.WorkflowMetadata memory metadata = + s_registry.getWorkflowMetadata(s_authorizedAddress, s_validWorkflowName); + + assertEq(metadata.workflowName, s_validWorkflowName); + assertEq(metadata.workflowID, s_validWorkflowID); + assertEq(metadata.binaryURL, s_validBinaryURL); + assertEq(metadata.configURL, s_validConfigURL); + assertEq(metadata.secretsURL, s_validSecretsURL); + } } diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadata.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadata.tree index f723f720528..215a2a4329f 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadata.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadata.tree @@ -1,5 +1,7 @@ WorkflowRegistry.getWorkflowMetadata ├── when the workflow exists with the owner and name │ └── it returns the correct metadata -└── when the workflow does not exist - └── it reverts with WorkflowDoesNotExist +├── when the workflow does not exist +│ └── it reverts with WorkflowDoesNotExist +└── when the registry is locked + └── it should behave the same as when the registry is not locked diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByDON.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByDON.t.sol index 14b3c96a07d..dbe0b23e5f0 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByDON.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByDON.t.sol @@ -6,8 +6,7 @@ import {WorkflowRegistryWithFixture} from "./WorkflowRegistryWithFixture.t.sol"; contract WorkflowRegistry_getWorkflowMetadataListByDON is WorkflowRegistryWithFixture { function test_WhenStartIs0() external view { - WorkflowRegistry.WorkflowMetadata[] memory workflows = - s_registry.getWorkflowMetadataListByDON(s_allowedDonID, 0, 10); + WorkflowRegistry.WorkflowMetadata[] memory workflows = s_registry.getWorkflowMetadataListByDON(s_allowedDonID, 0, 0); assertEq(workflows.length, 3); assertEq(workflows[0].workflowName, s_workflowName1); @@ -123,4 +122,34 @@ contract WorkflowRegistry_getWorkflowMetadataListByDON is WorkflowRegistryWithFi assertEq(workflows.length, 0); } + + function test_WhenTheRegistryIsLocked() external { + // Lock the registry + vm.prank(s_owner); + s_registry.lockRegistry(); + + // It should behave the same as when the registry is not locked + vm.prank(s_stranger); + WorkflowRegistry.WorkflowMetadata[] memory workflows = + s_registry.getWorkflowMetadataListByDON(s_allowedDonID, 0, 10); + + assertEq(workflows.length, 3); + assertEq(workflows[0].workflowName, s_workflowName1); + assertEq(workflows[0].workflowID, s_workflowID1); + assertEq(workflows[0].binaryURL, s_binaryURL1); + assertEq(workflows[0].configURL, s_configURL1); + assertEq(workflows[0].secretsURL, s_secretsURL1); + + assertEq(workflows[1].workflowName, s_workflowName2); + assertEq(workflows[1].workflowID, s_workflowID2); + assertEq(workflows[1].binaryURL, s_binaryURL2); + assertEq(workflows[1].configURL, s_configURL2); + assertEq(workflows[1].secretsURL, s_secretsURL2); + + assertEq(workflows[2].workflowName, s_workflowName3); + assertEq(workflows[2].workflowID, s_workflowID3); + assertEq(workflows[2].binaryURL, s_binaryURL3); + assertEq(workflows[2].configURL, s_configURL3); + assertEq(workflows[2].secretsURL, s_secretsURL3); + } } diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByDON.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByDON.tree index 1fd6b160b51..0fe6fab8b81 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByDON.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByDON.tree @@ -12,5 +12,7 @@ WorkflowRegistry.getWorkflowMetadataListByDON │ └── it returns the correct metadata list ├── when the DON has no workflows │ └── it returns an empty list -└── when start is greater than or equal to total workflows - └── it returns an empty list +├── when start is greater than or equal to total workflows +│ └── it returns an empty list +└── when the registry is locked + └── it should behave the same as when the registry is not locked diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByOwner.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByOwner.t.sol index 7eea75d0a02..ceeddca969b 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByOwner.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByOwner.t.sol @@ -5,24 +5,33 @@ import {WorkflowRegistry} from "../../dev/WorkflowRegistry.sol"; import {WorkflowRegistryWithFixture} from "./WorkflowRegistryWithFixture.t.sol"; contract WorkflowRegistry_getWorkflowMetadataListByOwner is WorkflowRegistryWithFixture { - function test_WhenStartIs0_AndLimitIs0() external view { + function test_WhenStartIs0() external view { WorkflowRegistry.WorkflowMetadata[] memory workflows = s_registry.getWorkflowMetadataListByOwner(s_authorizedAddress, 0, 0); assertEq(workflows.length, 3); assertEq(workflows[0].workflowName, s_workflowName1); + assertEq(workflows[0].owner, s_authorizedAddress); + assertEq(workflows[0].donID, s_allowedDonID); + assertTrue(workflows[0].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[0].workflowID, s_workflowID1); assertEq(workflows[0].binaryURL, s_binaryURL1); assertEq(workflows[0].configURL, s_configURL1); assertEq(workflows[0].secretsURL, s_secretsURL1); assertEq(workflows[1].workflowName, s_workflowName2); + assertEq(workflows[1].owner, s_authorizedAddress); + assertEq(workflows[1].donID, s_allowedDonID); + assertTrue(workflows[1].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[1].workflowID, s_workflowID2); assertEq(workflows[1].binaryURL, s_binaryURL2); assertEq(workflows[1].configURL, s_configURL2); assertEq(workflows[1].secretsURL, s_secretsURL2); assertEq(workflows[2].workflowName, s_workflowName3); + assertEq(workflows[2].owner, s_authorizedAddress); + assertEq(workflows[2].donID, s_allowedDonID); + assertTrue(workflows[2].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[2].workflowID, s_workflowID3); assertEq(workflows[2].binaryURL, s_binaryURL3); assertEq(workflows[2].configURL, s_configURL3); @@ -35,12 +44,18 @@ contract WorkflowRegistry_getWorkflowMetadataListByOwner is WorkflowRegistryWith assertEq(workflows.length, 2); assertEq(workflows[0].workflowName, s_workflowName2); + assertEq(workflows[0].owner, s_authorizedAddress); + assertEq(workflows[0].donID, s_allowedDonID); + assertTrue(workflows[0].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[0].workflowID, s_workflowID2); assertEq(workflows[0].binaryURL, s_binaryURL2); assertEq(workflows[0].configURL, s_configURL2); assertEq(workflows[0].secretsURL, s_secretsURL2); assertEq(workflows[1].workflowName, s_workflowName3); + assertEq(workflows[1].owner, s_authorizedAddress); + assertEq(workflows[1].donID, s_allowedDonID); + assertTrue(workflows[1].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[1].workflowID, s_workflowID3); assertEq(workflows[1].binaryURL, s_binaryURL3); assertEq(workflows[1].configURL, s_configURL3); @@ -54,12 +69,18 @@ contract WorkflowRegistry_getWorkflowMetadataListByOwner is WorkflowRegistryWith assertEq(workflows.length, 2); assertEq(workflows[0].workflowName, s_workflowName1); assertEq(workflows[0].workflowID, s_workflowID1); + assertEq(workflows[0].owner, s_authorizedAddress); + assertEq(workflows[0].donID, s_allowedDonID); + assertTrue(workflows[0].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[0].binaryURL, s_binaryURL1); assertEq(workflows[0].configURL, s_configURL1); assertEq(workflows[0].secretsURL, s_secretsURL1); assertEq(workflows[1].workflowName, s_workflowName2); assertEq(workflows[1].workflowID, s_workflowID2); + assertEq(workflows[1].owner, s_authorizedAddress); + assertEq(workflows[1].donID, s_allowedDonID); + assertTrue(workflows[1].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[1].binaryURL, s_binaryURL2); assertEq(workflows[1].configURL, s_configURL2); assertEq(workflows[1].secretsURL, s_secretsURL2); @@ -71,18 +92,27 @@ contract WorkflowRegistry_getWorkflowMetadataListByOwner is WorkflowRegistryWith assertEq(workflows.length, 3); assertEq(workflows[0].workflowName, s_workflowName1); + assertEq(workflows[0].owner, s_authorizedAddress); + assertEq(workflows[0].donID, s_allowedDonID); + assertTrue(workflows[0].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[0].workflowID, s_workflowID1); assertEq(workflows[0].binaryURL, s_binaryURL1); assertEq(workflows[0].configURL, s_configURL1); assertEq(workflows[0].secretsURL, s_secretsURL1); assertEq(workflows[1].workflowName, s_workflowName2); + assertEq(workflows[1].owner, s_authorizedAddress); + assertEq(workflows[1].donID, s_allowedDonID); + assertTrue(workflows[1].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[1].workflowID, s_workflowID2); assertEq(workflows[1].binaryURL, s_binaryURL2); assertEq(workflows[1].configURL, s_configURL2); assertEq(workflows[1].secretsURL, s_secretsURL2); assertEq(workflows[2].workflowName, s_workflowName3); + assertEq(workflows[2].owner, s_authorizedAddress); + assertEq(workflows[2].donID, s_allowedDonID); + assertTrue(workflows[2].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[2].workflowID, s_workflowID3); assertEq(workflows[2].binaryURL, s_binaryURL3); assertEq(workflows[2].configURL, s_configURL3); @@ -95,18 +125,27 @@ contract WorkflowRegistry_getWorkflowMetadataListByOwner is WorkflowRegistryWith assertEq(workflows.length, 3); assertEq(workflows[0].workflowName, s_workflowName1); + assertEq(workflows[0].owner, s_authorizedAddress); + assertEq(workflows[0].donID, s_allowedDonID); + assertTrue(workflows[0].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[0].workflowID, s_workflowID1); assertEq(workflows[0].binaryURL, s_binaryURL1); assertEq(workflows[0].configURL, s_configURL1); assertEq(workflows[0].secretsURL, s_secretsURL1); assertEq(workflows[1].workflowName, s_workflowName2); + assertEq(workflows[1].owner, s_authorizedAddress); + assertEq(workflows[1].donID, s_allowedDonID); + assertTrue(workflows[1].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[1].workflowID, s_workflowID2); assertEq(workflows[1].binaryURL, s_binaryURL2); assertEq(workflows[1].configURL, s_configURL2); assertEq(workflows[1].secretsURL, s_secretsURL2); assertEq(workflows[2].workflowName, s_workflowName3); + assertEq(workflows[2].owner, s_authorizedAddress); + assertEq(workflows[2].donID, s_allowedDonID); + assertTrue(workflows[2].status == WorkflowRegistry.WorkflowStatus.ACTIVE); assertEq(workflows[2].workflowID, s_workflowID3); assertEq(workflows[2].binaryURL, s_binaryURL3); assertEq(workflows[2].configURL, s_configURL3); @@ -116,7 +155,6 @@ contract WorkflowRegistry_getWorkflowMetadataListByOwner is WorkflowRegistryWith function test_WhenTheOwnerHasNoWorkflows() external view { WorkflowRegistry.WorkflowMetadata[] memory workflows = s_registry.getWorkflowMetadataListByOwner(s_unauthorizedAddress, 0, 10); - assertEq(workflows.length, 0); } @@ -126,4 +164,43 @@ contract WorkflowRegistry_getWorkflowMetadataListByOwner is WorkflowRegistryWith assertEq(workflows.length, 0); } + + function test_WhenTheRegistryIsLocked() external { + // Lock the registry + vm.prank(s_owner); + s_registry.lockRegistry(); + + // It should behave the same as when the registry is not locked + vm.prank(s_stranger); + WorkflowRegistry.WorkflowMetadata[] memory workflows = + s_registry.getWorkflowMetadataListByOwner(s_authorizedAddress, 0, 0); + + assertEq(workflows.length, 3); + assertEq(workflows[0].workflowName, s_workflowName1); + assertEq(workflows[0].owner, s_authorizedAddress); + assertEq(workflows[0].donID, s_allowedDonID); + assertTrue(workflows[0].status == WorkflowRegistry.WorkflowStatus.ACTIVE); + assertEq(workflows[0].workflowID, s_workflowID1); + assertEq(workflows[0].binaryURL, s_binaryURL1); + assertEq(workflows[0].configURL, s_configURL1); + assertEq(workflows[0].secretsURL, s_secretsURL1); + + assertEq(workflows[1].workflowName, s_workflowName2); + assertEq(workflows[1].owner, s_authorizedAddress); + assertEq(workflows[1].donID, s_allowedDonID); + assertTrue(workflows[1].status == WorkflowRegistry.WorkflowStatus.ACTIVE); + assertEq(workflows[1].workflowID, s_workflowID2); + assertEq(workflows[1].binaryURL, s_binaryURL2); + assertEq(workflows[1].configURL, s_configURL2); + assertEq(workflows[1].secretsURL, s_secretsURL2); + + assertEq(workflows[2].workflowName, s_workflowName3); + assertEq(workflows[2].owner, s_authorizedAddress); + assertEq(workflows[2].donID, s_allowedDonID); + assertTrue(workflows[2].status == WorkflowRegistry.WorkflowStatus.ACTIVE); + assertEq(workflows[2].workflowID, s_workflowID3); + assertEq(workflows[2].binaryURL, s_binaryURL3); + assertEq(workflows[2].configURL, s_configURL3); + assertEq(workflows[2].secretsURL, s_secretsURL3); + } } diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByOwner.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByOwner.tree index c2333473f39..ab076425542 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByOwner.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.getWorkflowMetadataListByOwner.tree @@ -2,7 +2,7 @@ WorkflowRegistry.getWorkflowMetadataListByOwner ├── when the owner has workflows │ ├── when start is 0 │ │ └── it returns the correct metadata list -│ ├── when start is greater than 0 and limit exceeds total +│ ├── when start is greater than 0 │ │ └── it returns the correct metadata list │ ├── when limit is less than total workflows │ │ └── it returns the correct metadata list @@ -12,5 +12,7 @@ WorkflowRegistry.getWorkflowMetadataListByOwner │ └── it returns the correct metadata list ├── when the owner has no workflows │ └── it returns an empty list -└── when start is greater than or equal to total workflows - └── it returns an empty list +├── when start is greater than or equal to total workflows +│ └── it returns an empty list +└── when the registry is locked + └── it should behave the same as when the registry is not locked diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.lockRegistry.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.lockRegistry.t.sol new file mode 100644 index 00000000000..5c93c56acee --- /dev/null +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.lockRegistry.t.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.24; + +import {Ownable2Step} from "../../../shared/access/Ownable2Step.sol"; +import {WorkflowRegistry} from "../../dev/WorkflowRegistry.sol"; +import {WorkflowRegistrySetup} from "./WorkflowRegistrySetup.t.sol"; + +contract WorkflowRegistry_lockRegistry is WorkflowRegistrySetup { + function test_RevertWhen_TheCallerIsNotTheContractOwner() external { + vm.expectRevert(Ownable2Step.OnlyCallableByOwner.selector); + s_registry.lockRegistry(); + } + + function test_WhenTheCallerIsTheContractOwner() external { + vm.expectEmit(true, true, false, false); + emit WorkflowRegistry.RegistryLockedV1(s_owner); + + vm.prank(s_owner); + s_registry.lockRegistry(); + + assertTrue(s_registry.isRegistryLocked()); + } +} diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.lockRegistry.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.lockRegistry.tree new file mode 100644 index 00000000000..8079c114e50 --- /dev/null +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.lockRegistry.tree @@ -0,0 +1,6 @@ +WorkflowRegistry.lockRegistry +├── when the caller is not the contract owner +│ └── it should revert +└── when the caller is the contract owner + ├── it should lock the registry + └── it should emit {RegistryLockedV1} diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.pauseWorkflow.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.pauseWorkflow.t.sol index a6ef679998a..1271808e85f 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.pauseWorkflow.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.pauseWorkflow.t.sol @@ -57,6 +57,10 @@ contract WorkflowRegistry_pauseWorkflow is WorkflowRegistrySetup { _removeDONFromAllowedDONs(s_allowedDonID); + // It should emit {WorkflowPausedV1} when the workflow is paused. + vm.expectEmit(); + emit WorkflowRegistry.WorkflowPausedV1(s_validWorkflowID, s_authorizedAddress, s_allowedDonID, s_validWorkflowName); + // Pause the workflow. vm.prank(s_authorizedAddress); s_registry.pauseWorkflow(s_validWorkflowKey); @@ -76,6 +80,10 @@ contract WorkflowRegistry_pauseWorkflow is WorkflowRegistrySetup { _removeAddressFromAuthorizedAddresses(s_authorizedAddress); _removeDONFromAllowedDONs(s_allowedDonID); + // It should emit {WorkflowPausedV1} when the workflow is paused. + vm.expectEmit(); + emit WorkflowRegistry.WorkflowPausedV1(s_validWorkflowID, s_authorizedAddress, s_allowedDonID, s_validWorkflowName); + // Pause the workflow. vm.prank(s_authorizedAddress); s_registry.pauseWorkflow(s_validWorkflowKey); @@ -93,6 +101,10 @@ contract WorkflowRegistry_pauseWorkflow is WorkflowRegistrySetup { _removeAddressFromAuthorizedAddresses(s_authorizedAddress); + // It should emit {WorkflowPausedV1} when the workflow is paused. + vm.expectEmit(); + emit WorkflowRegistry.WorkflowPausedV1(s_validWorkflowID, s_authorizedAddress, s_allowedDonID, s_validWorkflowName); + // Pause the workflow. vm.prank(s_authorizedAddress); s_registry.pauseWorkflow(s_validWorkflowKey); @@ -108,6 +120,10 @@ contract WorkflowRegistry_pauseWorkflow is WorkflowRegistrySetup { // Register a workflow first. _registerValidWorkflow(); + // It should emit {WorkflowPausedV1} when the workflow is paused. + vm.expectEmit(); + emit WorkflowRegistry.WorkflowPausedV1(s_validWorkflowID, s_authorizedAddress, s_allowedDonID, s_validWorkflowName); + // Pause the workflow. vm.prank(s_authorizedAddress); s_registry.pauseWorkflow(s_validWorkflowKey); diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.pauseWorkflow.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.pauseWorkflow.tree index 2cd2361b702..cbb75d0295c 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.pauseWorkflow.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.pauseWorkflow.tree @@ -9,8 +9,8 @@ WorkflowRegistry.pauseWorkflow │ └── it should revert └── when the workflow is active ├── when the donID is not allowed - │ ├── it should pause the workflow for an authorized address - │ └── it should pause the workflow for an unauthorized address + │ ├── it should pause the workflow for an authorized address and emit {WorkflowPausedV1} + │ └── it should pause the workflow for an unauthorized address and emit {WorkflowPausedV1} └── when the donID is allowed - ├── it should pause the workflow for an authorized address - └── it should pause the workflow for an unauthorized address + ├── it should pause the workflow for an authorized address and emit {WorkflowPausedV1} + └── it should pause the workflow for an unauthorized address and emit {WorkflowPausedV1} diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.registerWorkflow.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.registerWorkflow.t.sol index a6852b868dc..426fbfcc502 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.registerWorkflow.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.registerWorkflow.t.sol @@ -173,7 +173,7 @@ contract WorkflowRegistry_registerWorkflow is WorkflowRegistrySetup { vm.startPrank(s_authorizedAddress); // it should emit {WorkflowRegisteredV1} - vm.expectEmit(true, true, true, true); + vm.expectEmit(); emit WorkflowRegistry.WorkflowRegisteredV1( s_validWorkflowID, s_authorizedAddress, diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.unlockRegistry.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.unlockRegistry.t.sol new file mode 100644 index 00000000000..1cb2eb6429d --- /dev/null +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.unlockRegistry.t.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.24; + +import {Ownable2Step} from "../../../shared/access/Ownable2Step.sol"; +import {WorkflowRegistry} from "../../dev/WorkflowRegistry.sol"; +import {WorkflowRegistrySetup} from "./WorkflowRegistrySetup.t.sol"; + +contract WorkflowRegistry_unlockRegistry is WorkflowRegistrySetup { + function test_RevertWhen_TheCallerIsNotTheContractOwner() external { + vm.expectRevert(Ownable2Step.OnlyCallableByOwner.selector); + s_registry.unlockRegistry(); + } + + function test_WhenTheCallerIsTheContractOwner() external { + // Lock the registry first + vm.startPrank(s_owner); + s_registry.lockRegistry(); + + assertTrue(s_registry.isRegistryLocked()); + + // Unlock the registry + vm.expectEmit(true, true, false, false); + emit WorkflowRegistry.RegistryUnlockedV1(s_owner); + + s_registry.unlockRegistry(); + + assertFalse(s_registry.isRegistryLocked()); + vm.stopPrank(); + } +} diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.unlockRegistry.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.unlockRegistry.tree new file mode 100644 index 00000000000..c280b441a57 --- /dev/null +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.unlockRegistry.tree @@ -0,0 +1,6 @@ +WorkflowRegistry.unlockRegistry +├── when the caller is not the contract owner +│ └── it should revert +└── when the caller is the contract owner + ├── it should unlock the registry + └── it should emit {RegistryUnlockedV1} diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateAllowedDONs.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateAllowedDONs.t.sol index 63204fb8f96..bbf048909b5 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateAllowedDONs.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateAllowedDONs.t.sol @@ -7,7 +7,7 @@ import {WorkflowRegistrySetup} from "./WorkflowRegistrySetup.t.sol"; contract WorkflowRegistry_updateAllowedDONs is WorkflowRegistrySetup { function test_RevertWhen_TheCallerIsNotTheOwner() external { - vm.prank(s_nonOwner); + vm.prank(s_stranger); vm.expectRevert(Ownable2Step.OnlyCallableByOwner.selector); s_registry.updateAllowedDONs(new uint32[](0), true); @@ -36,7 +36,7 @@ contract WorkflowRegistry_updateAllowedDONs is WorkflowRegistrySetup { assertEq(allowedDONs.length, 1); // Expect the event to be emitted - vm.expectEmit(true, true, true, true); + vm.expectEmit(); emit WorkflowRegistry.AllowedDONsUpdatedV1(donIDsToAdd, true); // Call the function as the owner @@ -58,7 +58,7 @@ contract WorkflowRegistry_updateAllowedDONs is WorkflowRegistrySetup { assertEq(allowedDONs.length, 1); // Expect the event to be emitted - vm.expectEmit(true, true, true, true); + vm.expectEmit(); emit WorkflowRegistry.AllowedDONsUpdatedV1(donIDsToRemove, false); // Call the function as the owner diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateAuthorizedAddresses.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateAuthorizedAddresses.t.sol index ac9e9b94bea..01a3ded2c19 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateAuthorizedAddresses.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateAuthorizedAddresses.t.sol @@ -7,7 +7,7 @@ import {WorkflowRegistrySetup} from "./WorkflowRegistrySetup.t.sol"; contract WorkflowRegistry_updateAuthorizedAddresses is WorkflowRegistrySetup { function test_RevertWhen_TheCallerIsNotTheOwner() external { - vm.prank(s_nonOwner); + vm.prank(s_stranger); vm.expectRevert(Ownable2Step.OnlyCallableByOwner.selector); s_registry.updateAuthorizedAddresses(new address[](0), true); @@ -36,7 +36,7 @@ contract WorkflowRegistry_updateAuthorizedAddresses is WorkflowRegistrySetup { assertEq(authorizedAddresses.length, 1); // Expect the event to be emitted - vm.expectEmit(true, true, true, true); + vm.expectEmit(); emit WorkflowRegistry.AuthorizedAddressesUpdatedV1(addressesToAdd, true); // Call the function as the owner @@ -58,7 +58,7 @@ contract WorkflowRegistry_updateAuthorizedAddresses is WorkflowRegistrySetup { assertEq(authorizedAddresses.length, 1); // Expect the event to be emitted - vm.expectEmit(true, true, true, true); + vm.expectEmit(); emit WorkflowRegistry.AuthorizedAddressesUpdatedV1(addressesToRemove, false); // Call the function as the owner diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateWorkflow.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateWorkflow.t.sol index ff59989fe93..5058512ba7b 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateWorkflow.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistry.updateWorkflow.t.sol @@ -7,6 +7,8 @@ import {WorkflowRegistrySetup} from "./WorkflowRegistrySetup.t.sol"; contract WorkflowRegistry_updateWorkflow is WorkflowRegistrySetup { bytes32 private s_newValidWorkflowID = keccak256("newValidWorkflowID"); string private s_newValidSecretsURL = "https://example.com/new-secrets"; + string private s_newValidConfigURL = "https://example.com/new-config"; + string private s_newValidBinaryURL = "https://example.com/new-binary"; function test_RevertWhen_TheCallerIsNotAnAuthorizedAddress() external { // Register the workflow first as an authorized address. @@ -163,21 +165,21 @@ contract WorkflowRegistry_updateWorkflow is WorkflowRegistrySetup { // Update the workflow. // It should emit {WorkflowUpdatedV1}. - vm.expectEmit(true, true, true, true); + vm.expectEmit(); emit WorkflowRegistry.WorkflowUpdatedV1( s_validWorkflowID, s_authorizedAddress, s_allowedDonID, s_newValidWorkflowID, s_validWorkflowName, - s_validBinaryURL, - s_validConfigURL, + s_newValidBinaryURL, + s_newValidConfigURL, s_newValidSecretsURL ); vm.startPrank(s_authorizedAddress); s_registry.updateWorkflow( - s_validWorkflowKey, s_newValidWorkflowID, s_validBinaryURL, s_validConfigURL, s_newValidSecretsURL + s_validWorkflowKey, s_newValidWorkflowID, s_newValidBinaryURL, s_newValidConfigURL, s_newValidSecretsURL ); // It should update the workflow in s_workflows with the new values @@ -187,8 +189,8 @@ contract WorkflowRegistry_updateWorkflow is WorkflowRegistrySetup { assertEq(workflow.donID, s_allowedDonID); assertEq(workflow.workflowName, s_validWorkflowName); assertEq(workflow.workflowID, s_newValidWorkflowID); - assertEq(workflow.binaryURL, s_validBinaryURL); - assertEq(workflow.configURL, s_validConfigURL); + assertEq(workflow.binaryURL, s_newValidBinaryURL); + assertEq(workflow.configURL, s_newValidConfigURL); assertEq(workflow.secretsURL, s_newValidSecretsURL); assertTrue(workflow.status == WorkflowRegistry.WorkflowStatus.ACTIVE); diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistrySetup.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistrySetup.t.sol index c1a44e43c8e..b263b1cb79a 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistrySetup.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistry/WorkflowRegistrySetup.t.sol @@ -7,7 +7,7 @@ import {Test} from "forge-std/Test.sol"; contract WorkflowRegistrySetup is Test { WorkflowRegistry internal s_registry; address internal s_owner; - address internal s_nonOwner; + address internal s_stranger; address internal s_authorizedAddress; address internal s_unauthorizedAddress; uint32 internal s_allowedDonID; @@ -23,7 +23,7 @@ contract WorkflowRegistrySetup is Test { function setUp() public virtual { s_owner = makeAddr("owner"); - s_nonOwner = makeAddr("nonOwner"); + s_stranger = makeAddr("nonOwner"); s_authorizedAddress = makeAddr("authorizedAddress"); s_unauthorizedAddress = makeAddr("unauthorizedAddress"); s_allowedDonID = 1; diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.activateVersion.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.activateVersion.t.sol index 555d26e065f..a4c4975c3d4 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.activateVersion.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.activateVersion.t.sol @@ -1,33 +1,92 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -import {WorkflowRegistryManagerSetup} from "./WorkflowRegistryManagerSetup.t.sol"; - import {Ownable2Step} from "../../../shared/access/Ownable2Step.sol"; +import {WorkflowRegistryManager} from "../../dev/WorkflowRegistryManager.sol"; +import {WorkflowRegistryManagerSetup} from "./WorkflowRegistryManagerSetup.t.sol"; +import {Vm} from "forge-std/Vm.sol"; contract WorkflowRegistryManager_activateVersion is WorkflowRegistryManagerSetup { function test_RevertWhen_TheCallerIsNotTheOwner() external { // it should revert - vm.prank(s_nonOwner); + vm.prank(s_stranger); vm.expectRevert(Ownable2Step.OnlyCallableByOwner.selector); - s_registryManager.activateVersion(s_versionNumber); + s_registryManager.activateVersion(2); } // whenTheCallerIsTheOwner function test_RevertWhen_TheVersionNumberDoesNotExist() external { // it should revert + vm.prank(s_owner); + vm.expectRevert(abi.encodeWithSelector(WorkflowRegistryManager.VersionNotRegistered.selector, 5)); + s_registryManager.activateVersion(5); } // whenTheCallerIsTheOwner whenTheVersionNumberExists function test_RevertWhen_TheVersionNumberIsAlreadyActive() external { - // it should revert + // Deploy a mock registry and add that to the registry manager + _deployMockRegistryAndAddVersion(true); + + // Get the latest version number + uint32 versionNumber = s_registryManager.getLatestVersionNumber(); + + // Activate the same version + vm.prank(s_owner); + vm.expectRevert(abi.encodeWithSelector(WorkflowRegistryManager.VersionAlreadyActive.selector, versionNumber)); + s_registryManager.activateVersion(versionNumber); } - function test_WhenTheVersionNumberIsNotActive() external { - // it should deactivate the current active version (if any) - // it should activate the specified version and update s_activeVersionNumber - // it should add the version to s_versionNumberByAddressAndChainID - // it should emit VersionDeactivatedV1 (if a previous version was active) - // it should emit VersionActivatedV1 + function test_WhenTheVersionNumberIsNotActive_AndWhenThereAreNoActiveVersions() external { + // Deploy a mock registry and add but not activate it. + _deployMockRegistryAndAddVersion(false); + + // Get the latest version number, which should be 1. + uint32 versionNumber = s_registryManager.getLatestVersionNumber(); + assertEq(versionNumber, 1); + + // Start recording logs to check that VersionDeactivated is not emitted. + vm.recordLogs(); + + // Since there are no existing active versions, this should only activate the version and emit VersionActivated + vm.expectEmit(true, true, false, true); + emit WorkflowRegistryManager.VersionActivated(address(s_mockWorkflowRegistryContract), s_chainID, versionNumber); + + // Activate the version + vm.prank(s_owner); + s_registryManager.activateVersion(versionNumber); + + // Retrieve the recorded logs. + Vm.Log[] memory entries = vm.getRecordedLogs(); + + // Event signature hash for WorkflowForceUpdateSecretsRequestedV1. + bytes32 eventSignature = keccak256("VersionDeactivated(string,address,string)"); + + // Iterate through the logs to ensure VersionDeactivatedV1 was not emitted. + bool deactivateEventEmitted = false; + for (uint256 i = 0; i < entries.length; ++i) { + if (entries[i].topics[0] == eventSignature) { + deactivateEventEmitted = true; + break; + } + } + + // Assert that the event was not emitted. + assertFalse(deactivateEventEmitted); + + // Deploy another mock registry. + _deployMockRegistryAndAddVersion(false); + + // Get the latest version number, which should now be 2. + uint32 newVersionNumber = s_registryManager.getLatestVersionNumber(); + assertEq(newVersionNumber, 2); + + // It should now emit both VersionActivated and VersionDeactivated. + vm.expectEmit(true, true, false, true); + emit WorkflowRegistryManager.VersionActivated(address(s_mockWorkflowRegistryContract), s_chainID, newVersionNumber); + emit WorkflowRegistryManager.VersionDeactivated(address(s_mockWorkflowRegistryContract), s_chainID, versionNumber); + + // Activate the version + vm.prank(s_owner); + s_registryManager.activateVersion(newVersionNumber); } } diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.activateVersion.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.activateVersion.tree index eb95a4e794c..cee39a0db69 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.activateVersion.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.activateVersion.tree @@ -11,5 +11,5 @@ WorkflowRegistryManager.activateVersion ├── it should deactivate the current active version (if any) ├── it should activate the specified version and update s_activeVersionNumber ├── it should add the version to s_versionNumberByAddressAndChainID - ├── it should emit VersionDeactivatedV1 (if a previous version was active) - └── it should emit VersionActivatedV1 + ├── it should emit VersionDeactivated (if a previous version was active) + └── it should emit VersionActivated diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.addVersion.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.addVersion.t.sol index 940b15dfd54..218ac44eaa6 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.addVersion.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.addVersion.t.sol @@ -1,32 +1,103 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -contract WorkflowRegistryManageraddVersion { +import {Ownable2Step} from "../../../shared/access/Ownable2Step.sol"; +import {WorkflowRegistryManager} from "../../dev/WorkflowRegistryManager.sol"; +import {MockContract} from "../../mocks/MockContract.sol"; +import {MockWorkflowRegistryContract} from "../../mocks/MockWorkflowRegistryContract.sol"; +import {WorkflowRegistryManagerSetup} from "./WorkflowRegistryManagerSetup.t.sol"; + +contract WorkflowRegistryManager_addVersion is WorkflowRegistryManagerSetup { function test_RevertWhen_TheCallerIsNotTheOwner() external { - // it should revert + // Deploy the MockWorkflowRegistryContract contract + vm.prank(s_owner); + MockWorkflowRegistryContract mockContract = new MockWorkflowRegistryContract(); + + // Add it as a non owner + vm.prank(s_stranger); + vm.expectRevert(Ownable2Step.OnlyCallableByOwner.selector); + s_registryManager.addVersion(address(mockContract), s_chainID, s_deployedAt, true); } - modifier whenTheCallerIsTheOwner() { - _; + // whenTheCallerIsTheOwner + function test_RevertWhen_TheContractAddressIsInvalid() external { + // Deploy a random contract + MockContract mockContract = new MockContract(); + + // Add it to the WorkflowRegistryManager + vm.prank(s_owner); + vm.expectRevert(abi.encodeWithSelector(WorkflowRegistryManager.InvalidContractType.selector, address(mockContract))); + s_registryManager.addVersion(address(mockContract), s_chainID, s_deployedAt, true); } - function test_RevertWhen_TheContractAddressIsInvalid() external whenTheCallerIsTheOwner { - // it should revert + // whenTheCallerIsTheOwner + function test_RevertWhen_TheContractAddressIsValid() external { + // Add a 0 address to the WorkflowRegistryManager + vm.prank(s_owner); + vm.expectRevert(abi.encodeWithSelector(WorkflowRegistryManager.InvalidContractAddress.selector, address(0))); + s_registryManager.addVersion(address(0), s_chainID, s_deployedAt, true); } - modifier whenTheContractAddressIsValid() { - _; + // whenTheCallerIsTheOwner whenTheContractAddressIsValid + function test_RevertWhen_TheContractTypeIsInvalid() external { + // Deploy a random contract + MockContract mockContract = new MockContract(); + + // Add it to the WorkflowRegistryManager + vm.prank(s_owner); + vm.expectRevert(abi.encodeWithSelector(WorkflowRegistryManager.InvalidContractType.selector, address(mockContract))); + s_registryManager.addVersion(address(mockContract), s_chainID, s_deployedAt, true); } - function test_WhenAutoActivateIsTrue() external whenTheCallerIsTheOwner whenTheContractAddressIsValid { - // it should deactivate any currently active version - // it should activate the new version - // it should emit VersionAddedV1 after adding the version to s_versions - // it should emit VersionActivatedV1 + // whenTheCallerIsTheOwner whenTheContractAddressIsValid whenTheContractTypeIsValid + function test_WhenAutoActivateIsTrue() external { + // Get the latest version number, which should revert. + vm.expectRevert(WorkflowRegistryManager.NoVersionsRegistered.selector); + s_registryManager.getLatestVersionNumber(); + + // Deploy a MockWorkflowRegistryContract contract + MockWorkflowRegistryContract mockWfrContract = new MockWorkflowRegistryContract(); + + // Expect both VersionAdded and VersionActivated events to be emitted. + vm.expectEmit(true, true, false, true); + emit WorkflowRegistryManager.VersionAdded(address(mockWfrContract), s_chainID, s_deployedAt, 1); + emit WorkflowRegistryManager.VersionActivated(address(mockWfrContract), s_chainID, 1); + + // Add the MockWorkflowRegistryContract to the WorkflowRegistryManager + vm.prank(s_owner); + s_registryManager.addVersion(address(mockWfrContract), s_chainID, s_deployedAt, true); + + // Get the latest version number again, which should be 1. + uint32 versionNumber = s_registryManager.getLatestVersionNumber(); + assertEq(versionNumber, 1); + + // Get the latest active version number, which should also be 1. + uint32 activeVersionNumber = s_registryManager.getActiveVersionNumber(); + assertEq(activeVersionNumber, 1); } - function test_WhenAutoActivateIsFalse() external whenTheCallerIsTheOwner whenTheContractAddressIsValid { - // it should not activate the new version - // it should emit VersionAddedV1 after adding the version to s_versions + // whenTheCallerIsTheOwner whenTheContractAddressIsValid whenTheContractTypeIsValid + function test_WhenAutoActivateIsFalse() external { + // Get the latest version number, which should revert. + vm.expectRevert(WorkflowRegistryManager.NoVersionsRegistered.selector); + s_registryManager.getLatestVersionNumber(); + + // Deploy a MockWorkflowRegistryContract contract + MockWorkflowRegistryContract mockWfrContract = new MockWorkflowRegistryContract(); + + vm.expectEmit(true, true, false, true); + emit WorkflowRegistryManager.VersionAdded(address(mockWfrContract), s_chainID, s_deployedAt, 1); + + // Add the MockWorkflowRegistryContract to the WorkflowRegistryManager + vm.prank(s_owner); + s_registryManager.addVersion(address(mockWfrContract), s_chainID, s_deployedAt, false); + + // Get the latest version number again, which should be 1. + uint32 versionNumber = s_registryManager.getLatestVersionNumber(); + assertEq(versionNumber, 1); + + // Get the latest active version number, which should revert. + vm.expectRevert(WorkflowRegistryManager.NoActiveVersionAvailable.selector); + s_registryManager.getActiveVersionNumber(); } } diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.addVersion.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.addVersion.tree index 553db81dbe0..5e1c22b7840 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.addVersion.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.addVersion.tree @@ -5,11 +5,14 @@ WorkflowRegistryManager.addVersion ├── when the contract address is invalid │ └── it should revert └── when the contract address is valid - ├── when autoActivate is true - │ ├── it should deactivate any currently active version - │ ├── it should activate the new version - │ ├── it should emit VersionAddedV1 after adding the version to s_versions - │ └── it should emit VersionActivatedV1 - └── when autoActivate is false - ├── it should not activate the new version - └── it should emit VersionAddedV1 after adding the version to s_versions + ├── when the contract type is invalid + │ └── it should revert + └── when the contract type is valid + ├── when autoActivate is true + │ ├── it should deactivate any currently active version + │ ├── it should activate the new version + │ ├── it should emit VersionAdded after adding the version to s_versions + │ └── it should emit VersionActivated + └── when autoActivate is false + ├── it should not activate the new version + └── it should emit VersionAdded after adding the version to s_versions diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getActiveVersion.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getActiveVersion.t.sol index f20fafd5c95..92d59346032 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getActiveVersion.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getActiveVersion.t.sol @@ -1,12 +1,20 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -contract WorkflowRegistryManagergetActiveVersion { +import {WorkflowRegistryManager} from "../../dev/WorkflowRegistryManager.sol"; +import {WorkflowRegistryManagerSetup} from "./WorkflowRegistryManagerSetup.t.sol"; + +contract WorkflowRegistryManager_getActiveVersion is WorkflowRegistryManagerSetup { function test_WhenNoActiveVersionIsAvailable() external { - // it should revert with NoActiveVersionAvailable + vm.expectRevert(WorkflowRegistryManager.NoActiveVersionAvailable.selector); + s_registryManager.getActiveVersion(); } function test_WhenAnActiveVersionExists() external { - // it should return the active version details + _deployMockRegistryAndAddVersion(true); + WorkflowRegistryManager.Version memory activeVersion = s_registryManager.getActiveVersion(); + assertEq(activeVersion.contractAddress, address(s_mockWorkflowRegistryContract)); + assertEq(activeVersion.chainID, s_chainID); + assertEq(activeVersion.deployedAt, s_deployedAt); } } diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getActiveVersionNumber.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getActiveVersionNumber.t.sol new file mode 100644 index 00000000000..4167dcc803a --- /dev/null +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getActiveVersionNumber.t.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {WorkflowRegistryManager} from "../../dev/WorkflowRegistryManager.sol"; +import {WorkflowRegistryManagerSetup} from "./WorkflowRegistryManagerSetup.t.sol"; + +contract WorkflowRegistryManager_getActiveVersionNumber is WorkflowRegistryManagerSetup { + function test_WhenNoActiveVersionIsAvailable() external { + vm.expectRevert(WorkflowRegistryManager.NoActiveVersionAvailable.selector); + s_registryManager.getActiveVersionNumber(); + } + + function test_WhenAnActiveVersionExists() external { + _deployMockRegistryAndAddVersion(true); + uint32 activeVersionNumber = s_registryManager.getActiveVersionNumber(); + assertEq(activeVersionNumber, 1); + } +} diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getActiveVersionNumber.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getActiveVersionNumber.tree new file mode 100644 index 00000000000..7f6fb062eec --- /dev/null +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getActiveVersionNumber.tree @@ -0,0 +1,5 @@ +WorkflowRegistryManager.getActiveVersion +├── when no active version is available +│ └── it should revert with NoActiveVersionAvailable +└── when an active version exists + └── it should return the active version number diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getAllVersions.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getAllVersions.t.sol index 9719d21711a..ccdfacb474f 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getAllVersions.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getAllVersions.t.sol @@ -1,16 +1,50 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -contract WorkflowRegistryManagergetAllVersions { - function test_WhenRequestingWithInvalidStartIndex() external { - // it should return an empty array +import {WorkflowRegistryManager} from "../../dev/WorkflowRegistryManager.sol"; + +import {MockWorkflowRegistryContract} from "../../mocks/MockWorkflowRegistryContract.sol"; +import {WorkflowRegistryManagerSetup} from "./WorkflowRegistryManagerSetup.t.sol"; + +contract WorkflowRegistryManager_getAllVersions is WorkflowRegistryManagerSetup { + MockWorkflowRegistryContract internal s_mockContract1; + MockWorkflowRegistryContract internal s_mockContract2; + MockWorkflowRegistryContract internal s_mockContract3; + + function setUp() public override { + super.setUp(); + // Add 3 versions + s_mockContract1 = new MockWorkflowRegistryContract(); + s_mockContract2 = new MockWorkflowRegistryContract(); + s_mockContract3 = new MockWorkflowRegistryContract(); + + vm.startPrank(s_owner); + s_registryManager.addVersion(address(s_mockContract1), s_chainID, s_deployedAt, true); + s_registryManager.addVersion(address(s_mockContract2), s_chainID, s_deployedAt, false); + s_registryManager.addVersion(address(s_mockContract3), s_chainID, s_deployedAt, true); + vm.stopPrank(); + } + + function test_WhenRequestingWithInvalidStartIndex() external view { + // It should return an empty array. + WorkflowRegistryManager.Version[] memory versions = s_registryManager.getAllVersions(10, 1); + assertEq(versions.length, 0); } - function test_WhenRequestingWithValidStartIndexAndLimitWithinBounds() external { - // it should return the correct versions based on pagination + function test_WhenRequestingWithValidStartIndexAndLimitWithinBounds() external view { + // It should return the correct versions based on pagination. + WorkflowRegistryManager.Version[] memory versions = s_registryManager.getAllVersions(1, 2); + assertEq(versions.length, 2); + assertEq(versions[0].contractAddress, address(s_mockContract1)); + assertEq(versions[1].contractAddress, address(s_mockContract2)); } - function test_WhenLimitExceedsMaximumPaginationLimit() external { + function test_WhenLimitExceedsMaximumPaginationLimit() external view { // it should return results up to MAX_PAGINATION_LIMIT + WorkflowRegistryManager.Version[] memory versions = s_registryManager.getAllVersions(1, 200); + assertEq(versions.length, 3); + assertEq(versions[0].contractAddress, address(s_mockContract1)); + assertEq(versions[1].contractAddress, address(s_mockContract2)); + assertEq(versions[2].contractAddress, address(s_mockContract3)); } } diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersion.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersion.t.sol index 7c38eb6f8a7..9ca2347d8a6 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersion.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersion.t.sol @@ -1,12 +1,22 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -contract WorkflowRegistryManagergetLatestVersion { +import {WorkflowRegistryManager} from "../../dev/WorkflowRegistryManager.sol"; +import {WorkflowRegistryManagerSetup} from "./WorkflowRegistryManagerSetup.t.sol"; + +contract WorkflowRegistryManager_getLatestVersion is WorkflowRegistryManagerSetup { function test_WhenNoVersionsHaveBeenRegistered() external { - // it should revert with NoActiveVersionAvailable + // it should revert with NoVersionsRegistered + vm.expectRevert(WorkflowRegistryManager.NoVersionsRegistered.selector); + s_registryManager.getLatestVersion(); } function test_WhenVersionsHaveBeenRegistered() external { // it should return the latest registered version details + _deployMockRegistryAndAddVersion(true); + WorkflowRegistryManager.Version memory version = s_registryManager.getLatestVersion(); + assertEq(version.contractAddress, address(s_mockWorkflowRegistryContract)); + assertEq(version.chainID, s_chainID); + assertEq(version.deployedAt, s_deployedAt); } } diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersion.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersion.tree index 42012a0962f..d5d674f3d93 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersion.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersion.tree @@ -1,5 +1,5 @@ WorkflowRegistryManager.getLatestVersion ├── when no versions have been registered -│ └── it should revert with NoActiveVersionAvailable +│ └── it should revert with NoVersionsRegistered └── when versions have been registered └── it should return the latest registered version details diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersionNumber.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersionNumber.t.sol new file mode 100644 index 00000000000..4ac9afc6ea6 --- /dev/null +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersionNumber.t.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {WorkflowRegistryManager} from "../../dev/WorkflowRegistryManager.sol"; +import {WorkflowRegistryManagerSetup} from "./WorkflowRegistryManagerSetup.t.sol"; + +contract WorkflowRegistryManager_getLatestVersionNumber is WorkflowRegistryManagerSetup { + function test_WhenNoVersionsHaveBeenRegistered() external { + vm.expectRevert(WorkflowRegistryManager.NoVersionsRegistered.selector); + s_registryManager.getLatestVersionNumber(); + } + + function test_WhenVersionsHaveBeenRegistered() external { + _deployMockRegistryAndAddVersion(true); + uint32 latestVersionNumber = s_registryManager.getLatestVersionNumber(); + assertEq(latestVersionNumber, 1); + } +} diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersionNumber.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersionNumber.tree new file mode 100644 index 00000000000..6207f82f5be --- /dev/null +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getLatestVersionNumber.tree @@ -0,0 +1,5 @@ +WorkflowRegistryManager.getLatestVersionNumber +├── when no versions have been registered +│ └── it should revert with NoVersionsRegistered +└── when versions have been registered + └── it should return the latest registered version number diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersion.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersion.t.sol index 54b12211ca7..1c8ea44408f 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersion.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersion.t.sol @@ -1,12 +1,23 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -contract WorkflowRegistryManagergetVersion { +import {WorkflowRegistryManagerSetup} from "./WorkflowRegistryManagerSetup.t.sol"; +// import {MockWorkflowRegistryContract} from "../../mocks/MockWorkflowRegistryContract.sol"; +import {WorkflowRegistryManager} from "../../dev/WorkflowRegistryManager.sol"; + +contract WorkflowRegistryManager_getVersion is WorkflowRegistryManagerSetup { function test_WhenVersionNumberIsNotRegistered() external { // it should revert with VersionNotRegistered + vm.expectRevert(abi.encodeWithSelector(WorkflowRegistryManager.VersionNotRegistered.selector, 1)); + s_registryManager.getVersion(1); } function test_WhenVersionNumberIsRegistered() external { // it should return the correct version details + _deployMockRegistryAndAddVersion(true); + WorkflowRegistryManager.Version memory version = s_registryManager.getVersion(1); + assertEq(version.contractAddress, address(s_mockWorkflowRegistryContract)); + assertEq(version.chainID, s_chainID); + assertEq(version.deployedAt, s_deployedAt); } } diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersionNumber.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersionNumber.t.sol deleted file mode 100644 index 05ed4c43fda..00000000000 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersionNumber.t.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.24; - -contract WorkflowRegistryManagergetVersionNumber { - function test_WhenTheContractAddressIsInvalid() external { - // it should revert with InvalidContractAddress - } - - modifier whenTheContractAddressIsValid() { - _; - } - - function test_WhenNoVersionIsRegisteredForTheContractAddressAndChainIDCombination() - external - whenTheContractAddressIsValid - { - // it should revert with NoVersionsRegistered - } - - function test_WhenAVersionIsRegisteredForTheContractAddressAndChainIDCombination() - external - whenTheContractAddressIsValid - { - // it should return the correct version number - } -} diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersionNumberByContractAddressAndChainID.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersionNumberByContractAddressAndChainID.t.sol new file mode 100644 index 00000000000..a16ad878fc8 --- /dev/null +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersionNumberByContractAddressAndChainID.t.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {WorkflowRegistryManager} from "../../dev/WorkflowRegistryManager.sol"; +import {WorkflowRegistryManagerSetup} from "./WorkflowRegistryManagerSetup.t.sol"; + +contract WorkflowRegistryManager_getVersionNumberByContractAddressAndChainID is WorkflowRegistryManagerSetup { + function test_WhenTheContractAddressIsInvalid() external { + // It should revert with InvalidContractAddress + _deployMockRegistryAndAddVersion(true); + vm.expectRevert(abi.encodeWithSelector(WorkflowRegistryManager.InvalidContractAddress.selector, address(0))); + s_registryManager.getVersionNumberByContractAddressAndChainID(address(0), s_chainID); + } + + // whenTheContractAddressIsValid + function test_WhenNoVersionIsRegisteredForTheContractAddressAndChainIDCombination() external { + // It should revert with NoVersionsRegistered. + _deployMockRegistryAndAddVersion(true); + vm.expectRevert(WorkflowRegistryManager.NoVersionsRegistered.selector); + s_registryManager.getVersionNumberByContractAddressAndChainID(address(s_mockWorkflowRegistryContract), 20); + } + + // whenTheContractAddressIsValid + function test_WhenAVersionIsRegisteredForTheContractAddressAndChainIDCombination() external { + // It should return the correct version number. + _deployMockRegistryAndAddVersion(true); + uint32 versionNumber = + s_registryManager.getVersionNumberByContractAddressAndChainID(address(s_mockWorkflowRegistryContract), s_chainID); + assertEq(versionNumber, 1); + } +} diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersionNumber.tree b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersionNumberByContractAddressAndChainID.tree similarity index 87% rename from contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersionNumber.tree rename to contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersionNumberByContractAddressAndChainID.tree index 361e6192724..09c06911ce3 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersionNumber.tree +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManager.getVersionNumberByContractAddressAndChainID.tree @@ -1,4 +1,4 @@ -WorkflowRegistryManager.getVersionNumber +WorkflowRegistryManager.getVersionNumberByContractAddressAndChainID ├── when the contractAddress is invalid │ └── it should revert with InvalidContractAddress └── when the contractAddress is valid diff --git a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManagerSetup.t.sol b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManagerSetup.t.sol index c9e4a84da81..4e271aa5591 100644 --- a/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManagerSetup.t.sol +++ b/contracts/src/v0.8/workflow/test/WorkflowRegistryManager/WorkflowRegistryManagerSetup.t.sol @@ -2,27 +2,39 @@ pragma solidity 0.8.24; import {WorkflowRegistryManager} from "../../dev/WorkflowRegistryManager.sol"; +import {MockWorkflowRegistryContract} from "../../mocks/MockWorkflowRegistryContract.sol"; import {Test} from "forge-std/Test.sol"; contract WorkflowRegistryManagerSetup is Test { WorkflowRegistryManager internal s_registryManager; + MockWorkflowRegistryContract internal s_mockWorkflowRegistryContract; address internal s_owner; - address internal s_nonOwner; - address internal s_contractAddress; + address internal s_stranger; + address internal s_invalidContractAddress; uint64 internal s_chainID; - uint32 internal s_versionNumber; uint32 internal s_deployedAt; function setUp() public virtual { s_owner = makeAddr("owner"); - s_nonOwner = makeAddr("nonOwner"); - s_contractAddress = makeAddr("contractAddress"); + s_stranger = makeAddr("nonOwner"); + s_invalidContractAddress = makeAddr("contractAddress"); s_chainID = 1; - s_versionNumber = 1; s_deployedAt = uint32(block.timestamp); // Deploy the WorkflowRegistryManager contract vm.prank(s_owner); s_registryManager = new WorkflowRegistryManager(); } + + // Helper function to deploy the MockWorkflowRegistryContract and add it to the WorkflowRegistryManager + function _deployMockRegistryAndAddVersion( + bool activate + ) internal { + // Deploy the MockWorkflowRegistryContract contract + s_mockWorkflowRegistryContract = new MockWorkflowRegistryContract(); + + // Add the MockWorkflowRegistryContract to the WorkflowRegistryManager + vm.prank(s_owner); + s_registryManager.addVersion(address(s_mockWorkflowRegistryContract), s_chainID, s_deployedAt, activate); + } } diff --git a/core/capabilities/compute/test/fetch/cmd/main.go b/core/capabilities/compute/test/fetch/cmd/main.go index bc45b426005..44c6fb64601 100644 --- a/core/capabilities/compute/test/fetch/cmd/main.go +++ b/core/capabilities/compute/test/fetch/cmd/main.go @@ -12,12 +12,7 @@ import ( ) func BuildWorkflow(config []byte) *sdk.WorkflowSpecFactory { - workflow := sdk.NewWorkflowSpecFactory( - sdk.NewWorkflowParams{ - Name: "tester", - Owner: "ryan", - }, - ) + workflow := sdk.NewWorkflowSpecFactory() triggerCfg := basictrigger.TriggerConfig{Name: "trigger", Number: 100} trigger := triggerCfg.New(workflow) diff --git a/core/capabilities/compute/test/simple/cmd/main.go b/core/capabilities/compute/test/simple/cmd/main.go index 4ddacebe30b..92e4e52ef77 100644 --- a/core/capabilities/compute/test/simple/cmd/main.go +++ b/core/capabilities/compute/test/simple/cmd/main.go @@ -10,12 +10,7 @@ import ( ) func BuildWorkflow(config []byte) *sdk.WorkflowSpecFactory { - workflow := sdk.NewWorkflowSpecFactory( - sdk.NewWorkflowParams{ - Name: "tester", - Owner: "ryan", - }, - ) + workflow := sdk.NewWorkflowSpecFactory() triggerCfg := basictrigger.TriggerConfig{Name: "trigger", Number: 100} trigger := triggerCfg.New(workflow) diff --git a/core/cmd/app.go b/core/cmd/app.go index 53c96980de4..ad944f0d0a6 100644 --- a/core/cmd/app.go +++ b/core/cmd/app.go @@ -10,6 +10,7 @@ import ( "slices" "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" "github.com/urfave/cli" "github.com/smartcontractkit/chainlink/v2/core/build" @@ -85,6 +86,7 @@ func NewApp(s *Shell) *cli.App { } s.Logger = lggr + s.Registerer = prometheus.DefaultRegisterer // use the global DefaultRegisterer, should be safe since we only ever run one instance of the app per shell s.CloseLogger = closeFn s.Config = cfg diff --git a/core/cmd/shell.go b/core/cmd/shell.go index e4f4c5bd6e3..1edd53c1efc 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -25,6 +25,7 @@ import ( "github.com/gin-gonic/gin" "github.com/jmoiron/sqlx" "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" "github.com/urfave/cli" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" @@ -62,7 +63,7 @@ import ( var ( initGlobalsOnce sync.Once - prometheus *ginprom.Prometheus + ginPrometheus *ginprom.Prometheus grpcOpts loop.GRPCOpts ) @@ -71,7 +72,7 @@ func initGlobals(cfgProm config.Prometheus, cfgTracing config.Tracing, cfgTeleme var err error initGlobalsOnce.Do(func() { err = func() error { - prometheus = ginprom.New(ginprom.Namespace("service"), ginprom.Token(cfgProm.AuthToken())) + ginPrometheus = ginprom.New(ginprom.Namespace("service"), ginprom.Token(cfgProm.AuthToken())) grpcOpts = loop.NewGRPCOpts(nil) // default prometheus.Registerer otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) { @@ -139,6 +140,7 @@ type Shell struct { Renderer Config chainlink.GeneralConfig // initialized in Before Logger logger.Logger // initialized in Before + Registerer prometheus.Registerer // initialized in Before CloseLogger func() error // called in After AppFactory AppFactory KeyStoreAuthenticator TerminalKeyStoreAuthenticator @@ -178,14 +180,14 @@ func (s *Shell) configExitErr(validateFn func() error) cli.ExitCoder { // AppFactory implements the NewApplication method. type AppFactory interface { - NewApplication(ctx context.Context, cfg chainlink.GeneralConfig, appLggr logger.Logger, db *sqlx.DB, keyStoreAuthenticator TerminalKeyStoreAuthenticator) (chainlink.Application, error) + NewApplication(ctx context.Context, cfg chainlink.GeneralConfig, appLggr logger.Logger, appRegisterer prometheus.Registerer, db *sqlx.DB, keyStoreAuthenticator TerminalKeyStoreAuthenticator) (chainlink.Application, error) } // ChainlinkAppFactory is used to create a new Application. type ChainlinkAppFactory struct{} // NewApplication returns a new instance of the node with the given config. -func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.GeneralConfig, appLggr logger.Logger, db *sqlx.DB, keyStoreAuthenticator TerminalKeyStoreAuthenticator) (app chainlink.Application, err error) { +func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.GeneralConfig, appLggr logger.Logger, appRegisterer prometheus.Registerer, db *sqlx.DB, keyStoreAuthenticator TerminalKeyStoreAuthenticator) (app chainlink.Application, err error) { err = migrate.SetMigrationENVVars(cfg) if err != nil { return nil, err @@ -237,6 +239,7 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G // create the relayer-chain interoperators from application configuration relayerFactory := chainlink.RelayerFactory{ Logger: appLggr, + Registerer: appRegisterer, LoopRegistry: loopRegistry, GRPCOpts: grpcOpts, MercuryPool: mercuryPool, @@ -425,7 +428,7 @@ func (n ChainlinkRunner) Run(ctx context.Context, app chainlink.Application) err return errors.New("You must specify at least one port to listen on") } - handler, err := web.NewRouter(app, prometheus) + handler, err := web.NewRouter(app, ginPrometheus) if err != nil { return errors.Wrap(err, "failed to create web router") } diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index 6261d23ef82..bead4ba5afd 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -382,7 +382,7 @@ func (s *Shell) runNode(c *cli.Context) error { // From now on, DB locks and DB connection will be released on every return. // Keep watching on logger.Fatal* calls and os.Exit(), because defer will not be executed. - app, err := s.AppFactory.NewApplication(rootCtx, s.Config, s.Logger, ldb.DB(), s.KeyStoreAuthenticator) + app, err := s.AppFactory.NewApplication(rootCtx, s.Config, s.Logger, s.Registerer, ldb.DB(), s.KeyStoreAuthenticator) if err != nil { return s.errorOut(errors.Wrap(err, "fatal error instantiating application")) } @@ -629,7 +629,7 @@ func (s *Shell) RebroadcastTransactions(c *cli.Context) (err error) { } defer lggr.ErrorIfFn(db.Close, "Error closing db") - app, err := s.AppFactory.NewApplication(ctx, s.Config, lggr, db, s.KeyStoreAuthenticator) + app, err := s.AppFactory.NewApplication(ctx, s.Config, lggr, s.Registerer, db, s.KeyStoreAuthenticator) if err != nil { return s.errorOut(errors.Wrap(err, "fatal error instantiating application")) } @@ -1275,7 +1275,7 @@ func (s *Shell) RemoveBlocks(c *cli.Context) error { // From now on, DB locks and DB connection will be released on every return. // Keep watching on logger.Fatal* calls and os.Exit(), because defer will not be executed. - app, err := s.AppFactory.NewApplication(ctx, s.Config, s.Logger, ldb.DB(), s.KeyStoreAuthenticator) + app, err := s.AppFactory.NewApplication(ctx, s.Config, s.Logger, s.Registerer, ldb.DB(), s.KeyStoreAuthenticator) if err != nil { return s.errorOut(errors.Wrap(err, "fatal error instantiating application")) } diff --git a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go index ff7ccd3a5dd..78f051a4b9b 100644 --- a/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_from_mint_token_pool/burn_from_mint_token_pool.go @@ -74,23 +74,22 @@ type RateLimiterTokenBucket struct { type TokenPoolChainUpdate struct { RemoteChainSelector uint64 - Allowed bool - RemotePoolAddress []byte + RemotePoolAddresses [][]byte RemoteTokenAddress []byte OutboundRateLimiterConfig RateLimiterConfig InboundRateLimiterConfig RateLimiterConfig } var BurnFromMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b506040516200444a3803806200444a83398101604081905262000034916200085d565b83838383336000816200005a57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008d576200008d8162000159565b50506001600160a01b0384161580620000ad57506001600160a01b038116155b80620000c057506001600160a01b038216155b15620000df576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200013257604080516000815260208101909152620001329084620001d3565b506200014f925050506001600160a01b0385163060001962000330565b5050505062000a99565b336001600160a01b038216036200018357604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620001f4576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200027f5760008382815181106200021857620002186200096d565b602090810291909101015190506200023260028262000416565b1562000275576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620001f7565b5060005b81518110156200032b576000828281518110620002a457620002a46200096d565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002d0575062000322565b620002dd60028262000436565b1562000320576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000283565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000382573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a8919062000983565b620003b49190620009b3565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000410918691906200044d16565b50505050565b60006200042d836001600160a01b03841662000522565b90505b92915050565b60006200042d836001600160a01b03841662000626565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200049c906001600160a01b03851690849062000678565b8051909150156200032b5780806020019051810190620004bd9190620009c9565b6200032b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b600081815260018301602052604081205480156200061b57600062000549600183620009f4565b85549091506000906200055f90600190620009f4565b9050808214620005cb5760008660000182815481106200058357620005836200096d565b9060005260206000200154905080876000018481548110620005a957620005a96200096d565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620005df57620005df62000a0a565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000430565b600091505062000430565b60008181526001830160205260408120546200066f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000430565b50600062000430565b606062000689848460008562000691565b949350505050565b606082471015620006f45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000519565b600080866001600160a01b0316858760405162000712919062000a46565b60006040518083038185875af1925050503d806000811462000751576040519150601f19603f3d011682016040523d82523d6000602084013e62000756565b606091505b5090925090506200076a8783838762000775565b979650505050505050565b60608315620007e9578251600003620007e1576001600160a01b0385163b620007e15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000519565b508162000689565b620006898383815115620008005781518083602001fd5b8060405162461bcd60e51b815260040162000519919062000a64565b6001600160a01b03811681146200083257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000858816200081c565b919050565b600080600080608085870312156200087457600080fd5b845162000881816200081c565b602086810151919550906001600160401b0380821115620008a157600080fd5b818801915088601f830112620008b657600080fd5b815181811115620008cb57620008cb62000835565b8060051b604051601f19603f83011681018181108582111715620008f357620008f362000835565b60405291825284820192508381018501918b8311156200091257600080fd5b938501935b828510156200093b576200092b856200084b565b8452938501939285019262000917565b80985050505050505062000952604086016200084b565b915062000962606086016200084b565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156200099657600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156200043057620004306200099d565b600060208284031215620009dc57600080fd5b81518015158114620009ed57600080fd5b9392505050565b818103818111156200043057620004306200099d565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000a3d57818101518382015260200162000a23565b50506000910152565b6000825162000a5a81846020870162000a20565b9190910192915050565b602081526000825180602084015262000a8581604085016020870162000a20565b601f01601f19169190910160400192915050565b60805160a05160c05161393462000b16600039600081816104dd0152818161174a01526120fd0152600081816104b7015281816115ab0152611a000152600081816102390152818161028e015281816106e0015281816114cb0152818161192001528181611b180152818161209301526122e801526139346000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612a8b565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612aea565b6105f9565b6040516101d29190612b69565b6101ee6040518060400160405280601b81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e30000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612ba9565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612bc6565b6106a9565b604051905181526020016101d2565b6103006102fb366004612c4e565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612cba565b6108aa565b610300610a1e565b610300610349366004612ba9565b610aec565b6101c661035c366004612aea565b610b6d565b60015473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d3d565b610b84565b6040516101d29190612d78565b6103a7610c2b565b6040516101d29190612dd8565b6103c76103c2366004612aea565b610c3c565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612aea565b610d11565b610300610462366004612ba9565b610d3c565b61046f610e17565b6040516101d29190612e32565b6103c761048a366004612aea565b610ecf565b61030061049d366004612f9a565b610fa1565b6103006104b0366004612fdf565b61102a565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612ba9565b6114b0565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061062490613021565b80601f016020809104026020016040519081016040528092919081815260200182805461065090613021565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c48361311f565b6114c4565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612ba9565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612ba9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f5565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061174892505050565b50505050565b6108b26116f5565b6108bb83610b6d565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff83166000908152600760205260408120600401805461092990613021565b80601f016020809104026020016040519081016040528092919081815260200182805461095590613021565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d1838583613264565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a109392919061337e565b60405180910390a250505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a6f576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610af46116f5565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b60006105f3600567ffffffffffffffff84166118fe565b6040805180820190915260608082526020820152610ba9610ba4836133e2565b611919565b610bb68260600135611ae3565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c1084602001602081019061044f9190612aea565b81526040805160208181019092526000815291015292915050565b6060610c376002611b8c565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611b99565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061062490613021565b610d446116f5565b73ffffffffffffffffffffffffffffffffffffffff8116610d91576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e256005611b8c565b90506000815167ffffffffffffffff811115610e4357610e43612e74565b604051908082528060200260200182016040528015610e6c578160200160208202803683370190505b50905060005b8251811015610ec857828181518110610e8d57610e8d613484565b6020026020010151828281518110610ea757610ea7613484565b67ffffffffffffffff90921660209283029190910190910152600101610e72565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611b99565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fe1575060015473ffffffffffffffffffffffffffffffffffffffff163314155b1561101a576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611025838383611c4b565b505050565b6110326116f5565b60005b8181101561102557600083838381811061105157611051613484565b905060200281019061106391906134b3565b61106c906134f1565b90506110818160800151826020015115611d35565b6110948160a00151826020015115611d35565b8060200151156113905780516110b69060059067ffffffffffffffff16611e6e565b6110fb5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b60408101515115806111105750606081015151155b15611147576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061132890826135a5565b506060820151600582019061133d90826135a5565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061138394939291906136bf565b60405180910390a16114a7565b80516113a89060059067ffffffffffffffff16611e7a565b6113ed5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114566004830182612a3d565b611464600583016000612a3d565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611035565b6114b86116f5565b6114c181611e86565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115595760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611607573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162b9190613758565b15611662576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166f8160200151611f4a565b600061167e82602001516105f9565b90508051600014806116a2575080805190602001208260a001518051906020012014155b156116df578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612b69565b6116f182602001518360600151612070565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611746576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f000000000000000000000000000000000000000000000000000000000000000061179f576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118355760008382815181106117bf576117bf613484565b602002602001015190506117dd8160026120b790919063ffffffff16565b1561182c5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117a2565b5060005b815181101561102557600082828151811061185657611856613484565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361189a57506118f6565b6118a56002826120d9565b156118f45760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611839565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119ae5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a809190613758565b15611ab7576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ac481604001516120fb565b611ad1816020015161217a565b6114c1816020015182606001516122c8565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b158015611b7157600080fd5b505af1158015611b85573d6000803e3d6000fd5b5050505050565b606060006119128361230c565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c2782606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c0b91906137a4565b85608001516fffffffffffffffffffffffffffffffff16612367565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c5483610b6d565b611c96576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611ca1826000611d35565b67ffffffffffffffff83166000908152600760205260409020611cc49083612391565b611ccf816000611d35565b67ffffffffffffffff83166000908152600760205260409020611cf59060020182612391565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d28939291906137b7565b60405180910390a1505050565b815115611dfc5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611d8b575060408201516fffffffffffffffffffffffffffffffff16155b15611dc457816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f9919061383a565b80156116f1576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e35575060208201516fffffffffffffffffffffffffffffffff1615155b156116f157816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f9919061383a565b60006119128383612533565b60006119128383612582565b3373ffffffffffffffffffffffffffffffffffffffff821603611ed5576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611f5381610b6d565b611f95576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612014573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120389190613758565b6114c1576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116f190600201827f0000000000000000000000000000000000000000000000000000000000000000612675565b60006119128373ffffffffffffffffffffffffffffffffffffffff8416612582565b60006119128373ffffffffffffffffffffffffffffffffffffffff8416612533565b7f0000000000000000000000000000000000000000000000000000000000000000156114c15761212c6002826129f8565b6114c1576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b61218381610b6d565b6121c5576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561223e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122629190613876565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114c1576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116f190827f0000000000000000000000000000000000000000000000000000000000000000612675565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123485750505050509050919050565b6000612386856123778486613893565b61238190876138aa565b612a27565b90505b949350505050565b81546000906123ba90700100000000000000000000000000000000900463ffffffff16426137a4565b9050801561245c5760018301548354612402916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612367565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612482916fffffffffffffffffffffffffffffffff9081169116612a27565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d2890849061383a565b600081815260018301602052604081205461257a575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b6000818152600183016020526040812054801561266b5760006125a66001836137a4565b85549091506000906125ba906001906137a4565b905080821461261f5760008660000182815481106125da576125da613484565b90600052602060002001549050808760000184815481106125fd576125fd613484565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612630576126306138bd565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff16158061269c575081155b156126a657505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906126ec90700100000000000000000000000000000000900463ffffffff16426137a4565b905080156127ac578183111561272e576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127689083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612367565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128635773ffffffffffffffffffffffffffffffffffffffff841661280b576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129765760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128a790826137a4565b6128b1878a6137a4565b6128bb91906138aa565b6128c591906138ec565b905073ffffffffffffffffffffffffffffffffffffffff861661291e576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b61298085846137a4565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611912565b6000818310612a365781611912565b5090919050565b508054612a4990613021565b6000825580601f10612a59575050565b601f0160209004906000526020600020908101906114c191905b80821115612a875760008155600101612a73565b5090565b600060208284031215612a9d57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461191257600080fd5b803567ffffffffffffffff81168114612ae557600080fd5b919050565b600060208284031215612afc57600080fd5b61191282612acd565b6000815180845260005b81811015612b2b57602081850181015186830182015201612b0f565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119126020830184612b05565b73ffffffffffffffffffffffffffffffffffffffff811681146114c157600080fd5b8035612ae581612b7c565b600060208284031215612bbb57600080fd5b813561191281612b7c565b600060208284031215612bd857600080fd5b813567ffffffffffffffff811115612bef57600080fd5b8201610100818503121561191257600080fd5b60008083601f840112612c1457600080fd5b50813567ffffffffffffffff811115612c2c57600080fd5b6020830191508360208260051b8501011115612c4757600080fd5b9250929050565b60008060008060408587031215612c6457600080fd5b843567ffffffffffffffff80821115612c7c57600080fd5b612c8888838901612c02565b90965094506020870135915080821115612ca157600080fd5b50612cae87828801612c02565b95989497509550505050565b600080600060408486031215612ccf57600080fd5b612cd884612acd565b9250602084013567ffffffffffffffff80821115612cf557600080fd5b818601915086601f830112612d0957600080fd5b813581811115612d1857600080fd5b876020828501011115612d2a57600080fd5b6020830194508093505050509250925092565b600060208284031215612d4f57600080fd5b813567ffffffffffffffff811115612d6657600080fd5b820160a0818503121561191257600080fd5b602081526000825160406020840152612d946060840182612b05565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612dcf8282612b05565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e2657835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612df4565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e2657835167ffffffffffffffff1683529284019291840191600101612e4e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612ec757612ec7612e74565b60405290565b60405160c0810167ffffffffffffffff81118282101715612ec757612ec7612e74565b80151581146114c157600080fd5b8035612ae581612ef0565b80356fffffffffffffffffffffffffffffffff81168114612ae557600080fd5b600060608284031215612f3b57600080fd5b6040516060810181811067ffffffffffffffff82111715612f5e57612f5e612e74565b6040529050808235612f6f81612ef0565b8152612f7d60208401612f09565b6020820152612f8e60408401612f09565b60408201525092915050565b600080600060e08486031215612faf57600080fd5b612fb884612acd565b9250612fc78560208601612f29565b9150612fd68560808601612f29565b90509250925092565b60008060208385031215612ff257600080fd5b823567ffffffffffffffff81111561300957600080fd5b61301585828601612c02565b90969095509350505050565b600181811c9082168061303557607f821691505b60208210810361306e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f83011261308557600080fd5b813567ffffffffffffffff808211156130a0576130a0612e74565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156130e6576130e6612e74565b816040528381528660208588010111156130ff57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561313257600080fd5b61313a612ea3565b823567ffffffffffffffff8082111561315257600080fd5b61315e36838701613074565b835261316c60208601612acd565b602084015261317d60408601612b9e565b60408401526060850135606084015261319860808601612b9e565b608084015260a08501359150808211156131b157600080fd5b6131bd36838701613074565b60a084015260c08501359150808211156131d657600080fd5b6131e236838701613074565b60c084015260e08501359150808211156131fb57600080fd5b5061320836828601613074565b60e08301525092915050565b601f821115611025576000816000526020600020601f850160051c8101602086101561323d5750805b601f850160051c820191505b8181101561325c57828155600101613249565b505050505050565b67ffffffffffffffff83111561327c5761327c612e74565b6132908361328a8354613021565b83613214565b6000601f8411600181146132e257600085156132ac5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611b85565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156133315786850135825560209485019460019092019101613311565b508682101561336c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b6040815260006133916040830186612b05565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a082360312156133f457600080fd5b60405160a0810167ffffffffffffffff828210818311171561341857613418612e74565b81604052843591508082111561342d57600080fd5b5061343a36828601613074565b82525061344960208401612acd565b6020820152604083013561345c81612b7c565b604082015260608381013590820152608083013561347981612b7c565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126134e757600080fd5b9190910192915050565b6000610140823603121561350457600080fd5b61350c612ecd565b61351583612acd565b815261352360208401612efe565b6020820152604083013567ffffffffffffffff8082111561354357600080fd5b61354f36838701613074565b6040840152606085013591508082111561356857600080fd5b5061357536828601613074565b6060830152506135883660808501612f29565b608082015261359a3660e08501612f29565b60a082015292915050565b815167ffffffffffffffff8111156135bf576135bf612e74565b6135d3816135cd8454613021565b84613214565b602080601f83116001811461362657600084156135f05750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561325c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561367357888601518255948401946001909101908401613654565b50858210156136af57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526136e381840187612b05565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506137219050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612dcf565b60006020828403121561376a57600080fd5b815161191281612ef0565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f3613775565b67ffffffffffffffff8416815260e0810161380360208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612389565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561388857600080fd5b815161191281612b7c565b80820281158282048414176105f3576105f3613775565b808201808211156105f3576105f3613775565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600082613922577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004a6a38038062004a6a833981016040819052620000359162000869565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f8162000165565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0385811660805282811660c05260ff851660a052600480546001600160a01b031916918316919091179055825115801560e0526200013b576040805160008152602081019091526200013b9084620001df565b506200015a935050506001600160a01b0387169050306000196200033c565b505050505062000ac0565b336001600160a01b038216036200018f57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e05162000200576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200028b57600083828151811062000224576200022462000994565b602090810291909101015190506200023e60028262000422565b1562000281576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000203565b5060005b815181101562000337576000828281518110620002b057620002b062000994565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002dc57506200032e565b620002e960028262000442565b156200032c576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016200028f565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156200038e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003b49190620009aa565b620003c09190620009da565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200041c918691906200045916565b50505050565b600062000439836001600160a01b0384166200052e565b90505b92915050565b600062000439836001600160a01b03841662000632565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620004a8906001600160a01b03851690849062000684565b805190915015620003375780806020019051810190620004c99190620009f0565b620003375760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b60008181526001830160205260408120548015620006275760006200055560018362000a1b565b85549091506000906200056b9060019062000a1b565b9050808214620005d75760008660000182815481106200058f576200058f62000994565b9060005260206000200154905080876000018481548110620005b557620005b562000994565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620005eb57620005eb62000a31565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200043c565b60009150506200043c565b60008181526001830160205260408120546200067b575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200043c565b5060006200043c565b60606200069584846000856200069d565b949350505050565b606082471015620007005760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000525565b600080866001600160a01b031685876040516200071e919062000a6d565b60006040518083038185875af1925050503d80600081146200075d576040519150601f19603f3d011682016040523d82523d6000602084013e62000762565b606091505b509092509050620007768783838762000781565b979650505050505050565b60608315620007f5578251600003620007ed576001600160a01b0385163b620007ed5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000525565b508162000695565b6200069583838151156200080c5781518083602001fd5b8060405162461bcd60e51b815260040162000525919062000a8b565b6001600160a01b03811681146200083e57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008648162000828565b919050565b600080600080600060a086880312156200088257600080fd5b85516200088f8162000828565b8095505060208087015160ff81168114620008a957600080fd5b60408801519095506001600160401b0380821115620008c757600080fd5b818901915089601f830112620008dc57600080fd5b815181811115620008f157620008f162000841565b8060051b604051601f19603f8301168101818110858211171562000919576200091962000841565b60405291825284820192508381018501918c8311156200093857600080fd5b938501935b828510156200096157620009518562000857565b845293850193928501926200093d565b809850505050505050620009786060870162000857565b9150620009886080870162000857565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009bd57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156200043c576200043c620009c4565b60006020828403121562000a0357600080fd5b8151801515811462000a1457600080fd5b9392505050565b818103818111156200043c576200043c620009c4565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000a6457818101518382015260200162000a4a565b50506000910152565b6000825162000a8181846020870162000a47565b9190910192915050565b602081526000825180602084015262000aac81604085016020870162000a47565b601f01601f19169190910160400192915050565b60805160a05160c05160e051613f0762000b636000396000818161054f01528181611c5b01526126ac0152600081816105290152818161189f0152611f470152600081816102e001528181610ba901528181611a4801528181611b0201528181611b3601528181611b670152611bae0152600081816102470152818161029c01528181610708015281816120ca0152818161264201526128970152613f076000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610527578063e0351e131461054d578063e8a1da1714610573578063f2fde38b1461058657600080fd5b8063c0d78655146104d9578063c4bffe2b146104ec578063c75eea9c14610501578063cf7401f31461051457600080fd5b8063acfecf91116100de578063acfecf9114610426578063af58d59f14610439578063b0f479a1146104a8578063b7946580146104c657600080fd5b80639a4575b9146103d1578063a42a7b8b146103f1578063a7cd63b71461041157600080fd5b806354c8a4f31161017157806379ba50971161014b57806379ba5097146103855780637d54534e1461038d5780638926f54f146103a05780638da5cb5b146103b357600080fd5b806354c8a4f31461033f57806362ddd3c4146103545780636d3d1a581461036757600080fd5b8063240028e8116101ad578063240028e81461028c57806324f65ee7146102d9578063390775371461030a5780634c5ef0ed1461032c57600080fd5b806301ffc9a7146101d4578063181f5a77146101fc57806321df0da714610245575b600080fd5b6101e76101e2366004613057565b610599565b60405190151581526020015b60405180910390f35b6102386040518060400160405280601b81526020017f4275726e46726f6d4d696e74546f6b656e506f6f6c20312e352e31000000000081525081565b6040516101f391906130fd565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e761029a366004613132565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f3565b61031d61031836600461314f565b61067e565b604051905181526020016101f3565b6101e761033a3660046131a8565b61084d565b61035261034d366004613277565b610897565b005b6103526103623660046131a8565b610912565b60095473ffffffffffffffffffffffffffffffffffffffff16610267565b6103526109af565b61035261039b366004613132565b610a7d565b6101e76103ae3660046132e3565b610afe565b60015473ffffffffffffffffffffffffffffffffffffffff16610267565b6103e46103df3660046132fe565b610b15565b6040516101f39190613339565b6104046103ff3660046132e3565b610bee565b6040516101f39190613390565b610419610d59565b6040516101f39190613412565b6103526104343660046131a8565b610d6a565b61044c6104473660046132e3565b610e82565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610267565b6102386104d43660046132e3565b610f57565b6103526104e7366004613132565b611007565b6104f46110e2565b6040516101f3919061346c565b61044c61050f3660046132e3565b61119a565b6103526105223660046135f4565b61126c565b7f0000000000000000000000000000000000000000000000000000000000000000610267565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b610352610581366004613277565b6112f0565b610352610594366004613132565b611802565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061062c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061067857507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60408051602081019091526000815261069682611816565b60006106ef60608401356106ea6106b060c0870187613639565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3a92505050565b611afe565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961073d6060860160408701613132565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107aa57600080fd5b505af11580156107be573d6000803e3d6000fd5b506107d3925050506060840160408501613132565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161083191815260200190565b60405180910390a3604080516020810190915290815292915050565b600061088f838360405161086292919061369e565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611bee565b949350505050565b61089f611c06565b61090c84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611c5992505050565b50505050565b61091a611c06565b61092383610afe565b61096a576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109aa8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e0f92505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a00576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a85611c06565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610678600567ffffffffffffffff8416611bee565b6040805180820190915260608082526020820152610b3282611f09565b610b3f8260600135612095565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b998460200160208101906104d491906132e3565b8152602001610be66040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610c1790600501612137565b90506000815167ffffffffffffffff811115610c3557610c356134ae565b604051908082528060200260200182016040528015610c6857816020015b6060815260200190600190039081610c535790505b50905060005b8251811015610d515760086000848381518110610c8d57610c8d6136ae565b602002602001015181526020019081526020016000208054610cae906136dd565b80601f0160208091040260200160405190810160405280929190818152602001828054610cda906136dd565b8015610d275780601f10610cfc57610100808354040283529160200191610d27565b820191906000526020600020905b815481529060010190602001808311610d0a57829003601f168201915b5050505050828281518110610d3e57610d3e6136ae565b6020908102919091010152600101610c6e565b509392505050565b6060610d656002612137565b905090565b610d72611c06565b610d7b83610afe565b610dbd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610961565b610dfd8282604051610dd092919061369e565b604080519182900390912067ffffffffffffffff8616600090815260076020529190912060050190612144565b610e39578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161096193929190613779565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610e7592919061379d565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261067890612150565b67ffffffffffffffff81166000908152600760205260409020600401805460609190610f82906136dd565b80601f0160208091040260200160405190810160405280929190818152602001828054610fae906136dd565b8015610ffb5780601f10610fd057610100808354040283529160200191610ffb565b820191906000526020600020905b815481529060010190602001808311610fde57829003601f168201915b50505050509050919050565b61100f611c06565b73ffffffffffffffffffffffffffffffffffffffff811661105c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110f06005612137565b90506000815167ffffffffffffffff81111561110e5761110e6134ae565b604051908082528060200260200182016040528015611137578160200160208202803683370190505b50905060005b825181101561119357828181518110611158576111586136ae565b6020026020010151828281518110611172576111726136ae565b67ffffffffffffffff9092166020928302919091019091015260010161113d565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261067890612150565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906112ac575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156112e5576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b6109aa838383612202565b6112f8611c06565b60005b838110156114e5576000858583818110611317576113176136ae565b905060200201602081019061132c91906132e3565b9050611343600567ffffffffffffffff8316612144565b611385576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b67ffffffffffffffff811660009081526007602052604081206113aa90600501612137565b905060005b81518110156114165761140d8282815181106113cd576113cd6136ae565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161214490919063ffffffff16565b506001016113af565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600182018390556002820180549091169055600381018290559061147f6004830182612fea565b60058201600081816114918282613024565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916945060200192506114d3915050565b60405180910390a150506001016112fb565b5060005b818110156117fb576000838383818110611505576115056136ae565b905060200281019061151791906137b1565b6115209061387d565b9050611531816060015160006122ec565b611540816080015160006122ec565b80604001515160000361157f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115979060059067ffffffffffffffff16612429565b6115dc5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610961565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a90910299909316171790941695909517909255909202909117600382015590820151600482019061175f90826139f4565b5060005b8260200151518110156117a35761179b83600001518460200151838151811061178e5761178e6136ae565b6020026020010151611e0f565b600101611763565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516117e99493929190613b0e565b60405180910390a150506001016114e9565b5050505050565b61180a611c06565b61181381612435565b50565b61182961029a60a0830160808401613132565b6118885761183d60a0820160808301613132565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610961565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6118d460408401602085016132e3565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119699190613ba7565b156119a0576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119b86119b360408301602084016132e3565b6124f9565b6119d86119cb60408301602084016132e3565b61033a60a0840184613639565b611a1d576119e960a0820182613639565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161096192919061379d565b611813611a3060408301602084016132e3565b826060013561261f565b60008151600003611a6c57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611aa957816040517f953576f700000000000000000000000000000000000000000000000000000000815260040161096191906130fd565b600082806020019051810190611abf9190613bc4565b905060ff81111561067857826040517f953576f700000000000000000000000000000000000000000000000000000000815260040161096191906130fd565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611b34575081610678565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611ba857611b8c7f000000000000000000000000000000000000000000000000000000000000000083613c0c565b611b9790600a613d45565b611ba19084613d54565b9050610678565b611bd2827f0000000000000000000000000000000000000000000000000000000000000000613c0c565b611bdd90600a613d45565b611be79084613d8f565b9392505050565b60008181526001830160205260408120541515611be7565b60015473ffffffffffffffffffffffffffffffffffffffff163314611c57576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611cb0576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611d46576000838281518110611cd057611cd06136ae565b60200260200101519050611cee81600261266690919063ffffffff16565b15611d3d5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611cb3565b5060005b81518110156109aa576000828281518110611d6757611d676136ae565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611dab5750611e07565b611db6600282612688565b15611e055760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611d4a565b8051600003611e4a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff8416600090815260079092526040909120611e7c9060050182612429565b611eb65782826040517f393b8ad2000000000000000000000000000000000000000000000000000000008152600401610961929190613da6565b6000818152600860205260409020611ece83826139f4565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610e7591906130fd565b611f1c61029a60a0830160808401613132565b611f305761183d60a0820160808301613132565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611f7c60408401602085016132e3565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611fed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120119190613ba7565b15612048576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61206061205b6060830160408401613132565b6126aa565b61207861207360408301602084016132e3565b612729565b61181361208b60408301602084016132e3565b8260600135612877565b6040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906379cc679090604401600060405180830381600087803b15801561212357600080fd5b505af11580156117fb573d6000803e3d6000fd5b60606000611be7836128bb565b6000611be78383612916565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526121de82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426121c29190613dc9565b85608001516fffffffffffffffffffffffffffffffff16612a09565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61220b83610afe565b61224d576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610961565b6122588260006122ec565b67ffffffffffffffff8316600090815260076020526040902061227b9083612a31565b6122868160006122ec565b67ffffffffffffffff831660009081526007602052604090206122ac9060020182612a31565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516122df93929190613ddc565b60405180910390a1505050565b8151156123b75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612342575060408201516fffffffffffffffffffffffffffffffff16155b1561237b57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109619190613e5f565b80156123b3576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff161515806123f0575060208201516fffffffffffffffffffffffffffffffff1615155b156123b357816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109619190613e5f565b6000611be78383612bd3565b3373ffffffffffffffffffffffffffffffffffffffff821603612484576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61250281610afe565b612544576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156125c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125e79190613ba7565b611813576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b67ffffffffffffffff821660009081526007602052604090206123b390600201827f0000000000000000000000000000000000000000000000000000000000000000612c22565b6000611be78373ffffffffffffffffffffffffffffffffffffffff8416612916565b6000611be78373ffffffffffffffffffffffffffffffffffffffff8416612bd3565b7f000000000000000000000000000000000000000000000000000000000000000015611813576126db600282612fa5565b611813576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610961565b61273281610afe565b612774576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156127ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128119190613e9b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611813576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b67ffffffffffffffff821660009081526007602052604090206123b390827f0000000000000000000000000000000000000000000000000000000000000000612c22565b606081600001805480602002602001604051908101604052809291908181526020018280548015610ffb57602002820191906000526020600020905b8154815260200190600101908083116128f75750505050509050919050565b600081815260018301602052604081205480156129ff57600061293a600183613dc9565b855490915060009061294e90600190613dc9565b90508082146129b357600086600001828154811061296e5761296e6136ae565b9060005260206000200154905080876000018481548110612991576129916136ae565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806129c4576129c4613eb8565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610678565b6000915050610678565b6000612a2885612a198486613d8f565b612a239087613ee7565b612fd4565b95945050505050565b8154600090612a5a90700100000000000000000000000000000000900463ffffffff1642613dc9565b90508015612afc5760018301548354612aa2916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612a09565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612b22916fffffffffffffffffffffffffffffffff9081169116612fd4565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906122df908490613e5f565b6000818152600183016020526040812054612c1a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610678565b506000610678565b825474010000000000000000000000000000000000000000900460ff161580612c49575081155b15612c5357505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612c9990700100000000000000000000000000000000900463ffffffff1642613dc9565b90508015612d595781831115612cdb576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612d159083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612a09565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612e105773ffffffffffffffffffffffffffffffffffffffff8416612db8576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610961565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610961565b84831015612f235760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612e549082613dc9565b612e5e878a613dc9565b612e689190613ee7565b612e729190613d54565b905073ffffffffffffffffffffffffffffffffffffffff8616612ecb576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610961565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610961565b612f2d8584613dc9565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611be7565b6000818310612fe35781611be7565b5090919050565b508054612ff6906136dd565b6000825580601f10613006575050565b601f016020900490600052602060002090810190611813919061303e565b508054600082559060005260206000209081019061181391905b5b80821115613053576000815560010161303f565b5090565b60006020828403121561306957600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611be757600080fd5b6000815180845260005b818110156130bf576020818501810151868301820152016130a3565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611be76020830184613099565b73ffffffffffffffffffffffffffffffffffffffff8116811461181357600080fd5b60006020828403121561314457600080fd5b8135611be781613110565b60006020828403121561316157600080fd5b813567ffffffffffffffff81111561317857600080fd5b82016101008185031215611be757600080fd5b803567ffffffffffffffff811681146131a357600080fd5b919050565b6000806000604084860312156131bd57600080fd5b6131c68461318b565b9250602084013567ffffffffffffffff808211156131e357600080fd5b818601915086601f8301126131f757600080fd5b81358181111561320657600080fd5b87602082850101111561321857600080fd5b6020830194508093505050509250925092565b60008083601f84011261323d57600080fd5b50813567ffffffffffffffff81111561325557600080fd5b6020830191508360208260051b850101111561327057600080fd5b9250929050565b6000806000806040858703121561328d57600080fd5b843567ffffffffffffffff808211156132a557600080fd5b6132b18883890161322b565b909650945060208701359150808211156132ca57600080fd5b506132d78782880161322b565b95989497509550505050565b6000602082840312156132f557600080fd5b611be78261318b565b60006020828403121561331057600080fd5b813567ffffffffffffffff81111561332757600080fd5b820160a08185031215611be757600080fd5b6020815260008251604060208401526133556060840182613099565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612a288282613099565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613405577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526133f3858351613099565b945092850192908501906001016133b9565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561346057835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161342e565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561346057835167ffffffffffffffff1683529284019291840191600101613488565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613500576135006134ae565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561354d5761354d6134ae565b604052919050565b801515811461181357600080fd5b80356fffffffffffffffffffffffffffffffff811681146131a357600080fd5b60006060828403121561359557600080fd5b6040516060810181811067ffffffffffffffff821117156135b8576135b86134ae565b60405290508082356135c981613555565b81526135d760208401613563565b60208201526135e860408401613563565b60408201525092915050565b600080600060e0848603121561360957600080fd5b6136128461318b565b92506136218560208601613583565b91506136308560808601613583565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261366e57600080fd5b83018035915067ffffffffffffffff82111561368957600080fd5b60200191503681900382131561327057600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c908216806136f157607f821691505b60208210810361372a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612a28604083018486613730565b60208152600061088f602083018486613730565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181126137e557600080fd5b9190910192915050565b600082601f83011261380057600080fd5b813567ffffffffffffffff81111561381a5761381a6134ae565b61384b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613506565b81815284602083860101111561386057600080fd5b816020850160208301376000918101602001919091529392505050565b6000610120823603121561389057600080fd5b6138986134dd565b6138a18361318b565b815260208084013567ffffffffffffffff808211156138bf57600080fd5b9085019036601f8301126138d257600080fd5b8135818111156138e4576138e46134ae565b8060051b6138f3858201613506565b918252838101850191858101903684111561390d57600080fd5b86860192505b838310156139495782358581111561392b5760008081fd5b6139393689838a01016137ef565b8352509186019190860190613913565b808789015250505050604086013592508083111561396657600080fd5b5050613974368286016137ef565b6040830152506139873660608501613583565b60608201526139993660c08501613583565b608082015292915050565b601f8211156109aa576000816000526020600020601f850160051c810160208610156139cd5750805b601f850160051c820191505b818110156139ec578281556001016139d9565b505050505050565b815167ffffffffffffffff811115613a0e57613a0e6134ae565b613a2281613a1c84546136dd565b846139a4565b602080601f831160018114613a755760008415613a3f5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139ec565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613ac257888601518255948401946001909101908401613aa3565b5085821015613afe57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613b3281840187613099565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613b709050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612a28565b600060208284031215613bb957600080fd5b8151611be781613555565b600060208284031215613bd657600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561067857610678613bdd565b600181815b80851115613c7e57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613c6457613c64613bdd565b80851615613c7157918102915b93841c9390800290613c2a565b509250929050565b600082613c9557506001610678565b81613ca257506000610678565b8160018114613cb85760028114613cc257613cde565b6001915050610678565b60ff841115613cd357613cd3613bdd565b50506001821b610678565b5060208310610133831016604e8410600b8410161715613d01575081810a610678565b613d0b8383613c25565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613d3d57613d3d613bdd565b029392505050565b6000611be760ff841683613c86565b600082613d8a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761067857610678613bdd565b67ffffffffffffffff8316815260406020820152600061088f6040830184613099565b8181038181111561067857610678613bdd565b67ffffffffffffffff8416815260e08101613e2860208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261088f565b6060810161067882848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215613ead57600080fd5b8151611be781613110565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561067857610678613bdd56fea164736f6c6343000818000a", } var BurnFromMintTokenPoolABI = BurnFromMintTokenPoolMetaData.ABI var BurnFromMintTokenPoolBin = BurnFromMintTokenPoolMetaData.Bin -func DeployBurnFromMintTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, rmnProxy common.Address, router common.Address) (common.Address, *types.Transaction, *BurnFromMintTokenPool, error) { +func DeployBurnFromMintTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, localTokenDecimals uint8, allowlist []common.Address, rmnProxy common.Address, router common.Address) (common.Address, *types.Transaction, *BurnFromMintTokenPool, error) { parsed, err := BurnFromMintTokenPoolMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -99,7 +98,7 @@ func DeployBurnFromMintTokenPool(auth *bind.TransactOpts, backend bind.ContractB return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnFromMintTokenPoolBin), backend, token, allowlist, rmnProxy, router) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnFromMintTokenPoolBin), backend, token, localTokenDecimals, allowlist, rmnProxy, router) if err != nil { return common.Address{}, nil, nil, err } @@ -332,26 +331,26 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetRateLimitAd return _BurnFromMintTokenPool.Contract.GetRateLimitAdmin(&_BurnFromMintTokenPool.CallOpts) } -func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetRemotePools(opts *bind.CallOpts, remoteChainSelector uint64) ([][]byte, error) { var out []interface{} - err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getRemotePools", remoteChainSelector) if err != nil { - return *new([]byte), err + return *new([][]byte), err } - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + out0 := *abi.ConvertType(out[0], new([][]byte)).(*[][]byte) return out0, err } -func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { - return _BurnFromMintTokenPool.Contract.GetRemotePool(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetRemotePools(remoteChainSelector uint64) ([][]byte, error) { + return _BurnFromMintTokenPool.Contract.GetRemotePools(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) } -func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { - return _BurnFromMintTokenPool.Contract.GetRemotePool(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetRemotePools(remoteChainSelector uint64) ([][]byte, error) { + return _BurnFromMintTokenPool.Contract.GetRemotePools(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector) } func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { @@ -464,6 +463,50 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetToken() (co return _BurnFromMintTokenPool.Contract.GetToken(&_BurnFromMintTokenPool.CallOpts) } +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) GetTokenDecimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "getTokenDecimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) GetTokenDecimals() (uint8, error) { + return _BurnFromMintTokenPool.Contract.GetTokenDecimals(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) GetTokenDecimals() (uint8, error) { + return _BurnFromMintTokenPool.Contract.GetTokenDecimals(&_BurnFromMintTokenPool.CallOpts) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) IsRemotePool(opts *bind.CallOpts, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + var out []interface{} + err := _BurnFromMintTokenPool.contract.Call(opts, &out, "isRemotePool", remoteChainSelector, remotePoolAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) IsRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + return _BurnFromMintTokenPool.Contract.IsRemotePool(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCallerSession) IsRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + return _BurnFromMintTokenPool.Contract.IsRemotePool(&_BurnFromMintTokenPool.CallOpts, remoteChainSelector, remotePoolAddress) +} + func (_BurnFromMintTokenPool *BurnFromMintTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { var out []interface{} err := _BurnFromMintTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) @@ -586,6 +629,18 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) AcceptOwne return _BurnFromMintTokenPool.Contract.AcceptOwnership(&_BurnFromMintTokenPool.TransactOpts) } +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) AddRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "addRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) AddRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.AddRemotePool(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) AddRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.AddRemotePool(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { return _BurnFromMintTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) } @@ -598,16 +653,16 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) ApplyAllow return _BurnFromMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnFromMintTokenPool.TransactOpts, removes, adds) } -func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _BurnFromMintTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "applyChainUpdates", remoteChainSelectorsToRemove, chainsToAdd) } -func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _BurnFromMintTokenPool.Contract.ApplyChainUpdates(&_BurnFromMintTokenPool.TransactOpts, chains) +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) ApplyChainUpdates(remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.ApplyChainUpdates(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelectorsToRemove, chainsToAdd) } -func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _BurnFromMintTokenPool.Contract.ApplyChainUpdates(&_BurnFromMintTokenPool.TransactOpts, chains) +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) ApplyChainUpdates(remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.ApplyChainUpdates(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelectorsToRemove, chainsToAdd) } func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { @@ -634,6 +689,18 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) ReleaseOrM return _BurnFromMintTokenPool.Contract.ReleaseOrMint(&_BurnFromMintTokenPool.TransactOpts, releaseOrMintIn) } +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) RemoveRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnFromMintTokenPool.contract.Transact(opts, "removeRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) RemoveRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.RemoveRemotePool(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) RemoveRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnFromMintTokenPool.Contract.RemoveRemotePool(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { return _BurnFromMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) } @@ -658,18 +725,6 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) SetRateLim return _BurnFromMintTokenPool.Contract.SetRateLimitAdmin(&_BurnFromMintTokenPool.TransactOpts, rateLimitAdmin) } -func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _BurnFromMintTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) -} - -func (_BurnFromMintTokenPool *BurnFromMintTokenPoolSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _BurnFromMintTokenPool.Contract.SetRemotePool(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) -} - -func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _BurnFromMintTokenPool.Contract.SetRemotePool(&_BurnFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) -} - func (_BurnFromMintTokenPool *BurnFromMintTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { return _BurnFromMintTokenPool.contract.Transact(opts, "setRouter", newRouter) } @@ -2320,8 +2375,136 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseReleased(log t return event, nil } -type BurnFromMintTokenPoolRemotePoolSetIterator struct { - Event *BurnFromMintTokenPoolRemotePoolSet +type BurnFromMintTokenPoolRemotePoolAddedIterator struct { + Event *BurnFromMintTokenPoolRemotePoolAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnFromMintTokenPoolRemotePoolAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolRemotePoolAdded) + 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 + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnFromMintTokenPoolRemotePoolAdded) + 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() + } +} + +func (it *BurnFromMintTokenPoolRemotePoolAddedIterator) Error() error { + return it.fail +} + +func (it *BurnFromMintTokenPoolRemotePoolAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnFromMintTokenPoolRemotePoolAdded struct { + RemoteChainSelector uint64 + RemotePoolAddress []byte + Raw types.Log +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterRemotePoolAdded(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnFromMintTokenPoolRemotePoolAddedIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "RemotePoolAdded", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &BurnFromMintTokenPoolRemotePoolAddedIterator{contract: _BurnFromMintTokenPool.contract, event: "RemotePoolAdded", logs: logs, sub: sub}, nil +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchRemotePoolAdded(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolRemotePoolAdded, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "RemotePoolAdded", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnFromMintTokenPoolRemotePoolAdded) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "RemotePoolAdded", 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 +} + +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseRemotePoolAdded(log types.Log) (*BurnFromMintTokenPoolRemotePoolAdded, error) { + event := new(BurnFromMintTokenPoolRemotePoolAdded) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "RemotePoolAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnFromMintTokenPoolRemotePoolRemovedIterator struct { + Event *BurnFromMintTokenPoolRemotePoolRemoved contract *bind.BoundContract event string @@ -2332,7 +2515,7 @@ type BurnFromMintTokenPoolRemotePoolSetIterator struct { fail error } -func (it *BurnFromMintTokenPoolRemotePoolSetIterator) Next() bool { +func (it *BurnFromMintTokenPoolRemotePoolRemovedIterator) Next() bool { if it.fail != nil { return false @@ -2341,7 +2524,7 @@ func (it *BurnFromMintTokenPoolRemotePoolSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(BurnFromMintTokenPoolRemotePoolSet) + it.Event = new(BurnFromMintTokenPoolRemotePoolRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2356,7 +2539,7 @@ func (it *BurnFromMintTokenPoolRemotePoolSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(BurnFromMintTokenPoolRemotePoolSet) + it.Event = new(BurnFromMintTokenPoolRemotePoolRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2371,44 +2554,43 @@ func (it *BurnFromMintTokenPoolRemotePoolSetIterator) Next() bool { } } -func (it *BurnFromMintTokenPoolRemotePoolSetIterator) Error() error { +func (it *BurnFromMintTokenPoolRemotePoolRemovedIterator) Error() error { return it.fail } -func (it *BurnFromMintTokenPoolRemotePoolSetIterator) Close() error { +func (it *BurnFromMintTokenPoolRemotePoolRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -type BurnFromMintTokenPoolRemotePoolSet struct { +type BurnFromMintTokenPoolRemotePoolRemoved struct { RemoteChainSelector uint64 - PreviousPoolAddress []byte RemotePoolAddress []byte Raw types.Log } -func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnFromMintTokenPoolRemotePoolSetIterator, error) { +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) FilterRemotePoolRemoved(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnFromMintTokenPoolRemotePoolRemovedIterator, error) { var remoteChainSelectorRule []interface{} for _, remoteChainSelectorItem := range remoteChainSelector { remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + logs, sub, err := _BurnFromMintTokenPool.contract.FilterLogs(opts, "RemotePoolRemoved", remoteChainSelectorRule) if err != nil { return nil, err } - return &BurnFromMintTokenPoolRemotePoolSetIterator{contract: _BurnFromMintTokenPool.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil + return &BurnFromMintTokenPoolRemotePoolRemovedIterator{contract: _BurnFromMintTokenPool.contract, event: "RemotePoolRemoved", logs: logs, sub: sub}, nil } -func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchRemotePoolRemoved(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolRemotePoolRemoved, remoteChainSelector []uint64) (event.Subscription, error) { var remoteChainSelectorRule []interface{} for _, remoteChainSelectorItem := range remoteChainSelector { remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + logs, sub, err := _BurnFromMintTokenPool.contract.WatchLogs(opts, "RemotePoolRemoved", remoteChainSelectorRule) if err != nil { return nil, err } @@ -2418,8 +2600,8 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchRemotePoolSet( select { case log := <-logs: - event := new(BurnFromMintTokenPoolRemotePoolSet) - if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + event := new(BurnFromMintTokenPoolRemotePoolRemoved) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "RemotePoolRemoved", log); err != nil { return err } event.Raw = log @@ -2440,9 +2622,9 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) WatchRemotePoolSet( }), nil } -func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseRemotePoolSet(log types.Log) (*BurnFromMintTokenPoolRemotePoolSet, error) { - event := new(BurnFromMintTokenPoolRemotePoolSet) - if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { +func (_BurnFromMintTokenPool *BurnFromMintTokenPoolFilterer) ParseRemotePoolRemoved(log types.Log) (*BurnFromMintTokenPoolRemotePoolRemoved, error) { + event := new(BurnFromMintTokenPoolRemotePoolRemoved) + if err := _BurnFromMintTokenPool.contract.UnpackLog(event, "RemotePoolRemoved", log); err != nil { return nil, err } event.Raw = log @@ -2712,8 +2894,10 @@ func (_BurnFromMintTokenPool *BurnFromMintTokenPool) ParseLog(log types.Log) (ge return _BurnFromMintTokenPool.ParseRateLimitAdminSet(log) case _BurnFromMintTokenPool.abi.Events["Released"].ID: return _BurnFromMintTokenPool.ParseReleased(log) - case _BurnFromMintTokenPool.abi.Events["RemotePoolSet"].ID: - return _BurnFromMintTokenPool.ParseRemotePoolSet(log) + case _BurnFromMintTokenPool.abi.Events["RemotePoolAdded"].ID: + return _BurnFromMintTokenPool.ParseRemotePoolAdded(log) + case _BurnFromMintTokenPool.abi.Events["RemotePoolRemoved"].ID: + return _BurnFromMintTokenPool.ParseRemotePoolRemoved(log) case _BurnFromMintTokenPool.abi.Events["RouterUpdated"].ID: return _BurnFromMintTokenPool.ParseRouterUpdated(log) case _BurnFromMintTokenPool.abi.Events["TokensConsumed"].ID: @@ -2776,8 +2960,12 @@ func (BurnFromMintTokenPoolReleased) Topic() common.Hash { return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") } -func (BurnFromMintTokenPoolRemotePoolSet) Topic() common.Hash { - return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +func (BurnFromMintTokenPoolRemotePoolAdded) Topic() common.Hash { + return common.HexToHash("0x7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea") +} + +func (BurnFromMintTokenPoolRemotePoolRemoved) Topic() common.Hash { + return common.HexToHash("0x52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d76") } func (BurnFromMintTokenPoolRouterUpdated) Topic() common.Hash { @@ -2803,7 +2991,7 @@ type BurnFromMintTokenPoolInterface interface { GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) - GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + GetRemotePools(opts *bind.CallOpts, remoteChainSelector uint64) ([][]byte, error) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) @@ -2815,6 +3003,10 @@ type BurnFromMintTokenPoolInterface interface { GetToken(opts *bind.CallOpts) (common.Address, error) + GetTokenDecimals(opts *bind.CallOpts) (uint8, error) + + IsRemotePool(opts *bind.CallOpts, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) @@ -2827,20 +3019,22 @@ type BurnFromMintTokenPoolInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + AddRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) - ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + ApplyChainUpdates(opts *bind.TransactOpts, remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + RemoveRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) - SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) - SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) @@ -2923,11 +3117,17 @@ type BurnFromMintTokenPoolInterface interface { ParseReleased(log types.Log) (*BurnFromMintTokenPoolReleased, error) - FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnFromMintTokenPoolRemotePoolSetIterator, error) + FilterRemotePoolAdded(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnFromMintTokenPoolRemotePoolAddedIterator, error) + + WatchRemotePoolAdded(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolRemotePoolAdded, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolAdded(log types.Log) (*BurnFromMintTokenPoolRemotePoolAdded, error) + + FilterRemotePoolRemoved(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnFromMintTokenPoolRemotePoolRemovedIterator, error) - WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + WatchRemotePoolRemoved(opts *bind.WatchOpts, sink chan<- *BurnFromMintTokenPoolRemotePoolRemoved, remoteChainSelector []uint64) (event.Subscription, error) - ParseRemotePoolSet(log types.Log) (*BurnFromMintTokenPoolRemotePoolSet, error) + ParseRemotePoolRemoved(log types.Log) (*BurnFromMintTokenPoolRemotePoolRemoved, error) FilterRouterUpdated(opts *bind.FilterOpts) (*BurnFromMintTokenPoolRouterUpdatedIterator, error) diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go index c43083c2585..1a83c0a1cb6 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go @@ -74,23 +74,22 @@ type RateLimiterTokenBucket struct { type TokenPoolChainUpdate struct { RemoteChainSelector uint64 - Allowed bool - RemotePoolAddress []byte + RemotePoolAddresses [][]byte RemoteTokenAddress []byte OutboundRateLimiterConfig RateLimiterConfig InboundRateLimiterConfig RateLimiterConfig } var BurnMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b5060405162003fee38038062003fee8339810160408190526200003491620004e5565b83838383336000816200005a57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008d576200008d8162000140565b50506001600160a01b0384161580620000ad57506001600160a01b038116155b80620000c057506001600160a01b038216155b15620000df576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200013257604080516000815260208101909152620001329084620001ba565b505050505050505062000643565b336001600160a01b038216036200016a57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620001db576040516335f4a7b360e01b815260040160405180910390fd5b60005b825181101562000266576000838281518110620001ff57620001ff620005f5565b602090810291909101015190506200021960028262000317565b156200025c576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620001de565b5060005b8151811015620003125760008282815181106200028b576200028b620005f5565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002b7575062000309565b620002c460028262000337565b1562000307576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016200026a565b505050565b60006200032e836001600160a01b0384166200034e565b90505b92915050565b60006200032e836001600160a01b03841662000452565b6000818152600183016020526040812054801562000447576000620003756001836200060b565b85549091506000906200038b906001906200060b565b9050808214620003f7576000866000018281548110620003af57620003af620005f5565b9060005260206000200154905080876000018481548110620003d557620003d5620005f5565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200040b576200040b6200062d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000331565b600091505062000331565b60008181526001830160205260408120546200049b5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000331565b50600062000331565b6001600160a01b0381168114620004ba57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620004e081620004a4565b919050565b60008060008060808587031215620004fc57600080fd5b84516200050981620004a4565b602086810151919550906001600160401b03808211156200052957600080fd5b818801915088601f8301126200053e57600080fd5b815181811115620005535762000553620004bd565b8060051b604051601f19603f830116810181811085821117156200057b576200057b620004bd565b60405291825284820192508381018501918b8311156200059a57600080fd5b938501935b82851015620005c357620005b385620004d3565b845293850193928501926200059f565b809850505050505050620005da60408601620004d3565b9150620005ea60608601620004d3565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b818103818111156200033157634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05161392e620006c0600039600081816104dd0152818161174a01526120f70152600081816104b7015281816115ab0152611a000152600081816102390152818161028e015281816106e0015281816114cb0152818161192001528181611b120152818161208d01526122e2015261392e6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc146104a2578063dc0bd971146104b5578063e0351e13146104db578063f2fde38b1461050157600080fd5b8063c4bffe2b14610467578063c75eea9c1461047c578063cf7401f31461048f57600080fd5b8063b0f479a1116100c8578063b0f479a114610423578063b794658014610441578063c0d786551461045457600080fd5b80639a4575b91461037f578063a7cd63b71461039f578063af58d59f146103b457600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103335780637d54534e1461033b5780638926f54f1461034e5780638da5cb5b1461036157600080fd5b806354c8a4f3146102ed5780636d3d1a581461030257806378a010b21461032057600080fd5b806321df0da71161018c57806321df0da714610237578063240028e81461027e57806339077537146102cb57600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612a85565b610514565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612ae4565b6105f9565b6040516101d29190612b63565b6101ee6040518060400160405280601781526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e3000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c661028c366004612ba3565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102de6102d9366004612bc0565b6106a9565b604051905181526020016101d2565b6103006102fb366004612c48565b61082f565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610259565b61030061032e366004612cb4565b6108aa565b610300610a1e565b610300610349366004612ba3565b610aec565b6101c661035c366004612ae4565b610b6d565b60015473ffffffffffffffffffffffffffffffffffffffff16610259565b61039261038d366004612d37565b610b84565b6040516101d29190612d72565b6103a7610c2b565b6040516101d29190612dd2565b6103c76103c2366004612ae4565b610c3c565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610259565b6101ee61044f366004612ae4565b610d11565b610300610462366004612ba3565b610d3c565b61046f610e17565b6040516101d29190612e2c565b6103c761048a366004612ae4565b610ecf565b61030061049d366004612f94565b610fa1565b6103006104b0366004612fd9565b61102a565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61030061050f366004612ba3565b6114b0565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106249061301b565b80601f01602080910402602001604051908101604052809291908181526020018280546106509061301b565b801561069d5780601f106106725761010080835404028352916020019161069d565b820191906000526020600020905b81548152906001019060200180831161068057829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c96106c483613119565b6114c4565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107156060850160408601612ba3565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b506107ae925050506060830160408401612ba3565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161081091815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108376116f5565b6108a48484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061174892505050565b50505050565b6108b26116f5565b6108bb83610b6d565b610902576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109299061301b565b80601f01602080910402602001604051908101604052809291908181526020018280546109559061301b565b80156109a25780601f10610977576101008083540402835291602001916109a2565b820191906000526020600020905b81548152906001019060200180831161098557829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109d183858361325e565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a1093929190613378565b60405180910390a250505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a6f576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610af46116f5565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b60006105f3600567ffffffffffffffff84166118fe565b6040805180820190915260608082526020820152610ba9610ba4836133dc565b611919565b610bb68260600135611ae3565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c1084602001602081019061044f9190612ae4565b81526040805160208181019092526000815291015292915050565b6060610c376002611b86565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f390611b93565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106249061301b565b610d446116f5565b73ffffffffffffffffffffffffffffffffffffffff8116610d91576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e256005611b86565b90506000815167ffffffffffffffff811115610e4357610e43612e6e565b604051908082528060200260200182016040528015610e6c578160200160208202803683370190505b50905060005b8251811015610ec857828181518110610e8d57610e8d61347e565b6020026020010151828281518110610ea757610ea761347e565b67ffffffffffffffff90921660209283029190910190910152600101610e72565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f390611b93565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fe1575060015473ffffffffffffffffffffffffffffffffffffffff163314155b1561101a576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b611025838383611c45565b505050565b6110326116f5565b60005b818110156110255760008383838181106110515761105161347e565b905060200281019061106391906134ad565b61106c906134eb565b90506110818160800151826020015115611d2f565b6110948160a00151826020015115611d2f565b8060200151156113905780516110b69060059067ffffffffffffffff16611e68565b6110fb5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b60408101515115806111105750606081015151155b15611147576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c17909116961515029590951790985590810151940151938116931690910291909117600382015591519091906004820190611328908261359f565b506060820151600582019061133d908261359f565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061138394939291906136b9565b60405180910390a16114a7565b80516113a89060059067ffffffffffffffff16611e74565b6113ed5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f9565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114566004830182612a37565b611464600583016000612a37565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611035565b6114b86116f5565b6114c181611e80565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115595760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611607573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162b9190613752565b15611662576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166f8160200151611f44565b600061167e82602001516105f9565b90508051600014806116a2575080805190602001208260a001518051906020012014155b156116df578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f99190612b63565b6116f18260200151836060015161206a565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611746576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f000000000000000000000000000000000000000000000000000000000000000061179f576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118355760008382815181106117bf576117bf61347e565b602002602001015190506117dd8160026120b190919063ffffffff16565b1561182c5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506001016117a2565b5060005b81518110156110255760008282815181106118565761185661347e565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361189a57506118f6565b6118a56002826120d3565b156118f45760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611839565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119ae5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f9565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a809190613752565b15611ab7576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ac481604001516120f5565b611ad18160200151612174565b6114c1816020015182606001516122c2565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015611b6b57600080fd5b505af1158015611b7f573d6000803e3d6000fd5b5050505050565b6060600061191283612306565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c2182606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c05919061379e565b85608001516fffffffffffffffffffffffffffffffff16612361565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c4e83610b6d565b611c90576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f9565b611c9b826000611d2f565b67ffffffffffffffff83166000908152600760205260409020611cbe908361238b565b611cc9816000611d2f565b67ffffffffffffffff83166000908152600760205260409020611cef906002018261238b565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d22939291906137b1565b60405180910390a1505050565b815115611df65781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611d85575060408201516fffffffffffffffffffffffffffffffff16155b15611dbe57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f99190613834565b80156116f1576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e2f575060208201516fffffffffffffffffffffffffffffffff1615155b156116f157816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f99190613834565b6000611912838361252d565b6000611912838361257c565b3373ffffffffffffffffffffffffffffffffffffffff821603611ecf576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611f4d81610b6d565b611f8f576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561200e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120329190613752565b6114c1576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116f190600201827f000000000000000000000000000000000000000000000000000000000000000061266f565b60006119128373ffffffffffffffffffffffffffffffffffffffff841661257c565b60006119128373ffffffffffffffffffffffffffffffffffffffff841661252d565b7f0000000000000000000000000000000000000000000000000000000000000000156114c1576121266002826129f2565b6114c1576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f9565b61217d81610b6d565b6121bf576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f9565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225c9190613870565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114c1576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f9565b67ffffffffffffffff821660009081526007602052604090206116f190827f000000000000000000000000000000000000000000000000000000000000000061266f565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069d57602002820191906000526020600020905b8154815260200190600101908083116123425750505050509050919050565b600061238085612371848661388d565b61237b90876138a4565b612a21565b90505b949350505050565b81546000906123b490700100000000000000000000000000000000900463ffffffff164261379e565b9050801561245657600183015483546123fc916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612361565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461247c916fffffffffffffffffffffffffffffffff9081169116612a21565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d22908490613834565b6000818152600183016020526040812054612574575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f3565b5060006105f3565b600081815260018301602052604081205480156126655760006125a060018361379e565b85549091506000906125b49060019061379e565b90508082146126195760008660000182815481106125d4576125d461347e565b90600052602060002001549050808760000184815481106125f7576125f761347e565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061262a5761262a6138b7565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f3565b60009150506105f3565b825474010000000000000000000000000000000000000000900460ff161580612696575081155b156126a057505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906126e690700100000000000000000000000000000000900463ffffffff164261379e565b905080156127a65781831115612728576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127629083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612361565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561285d5773ffffffffffffffffffffffffffffffffffffffff8416612805576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f9565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f9565b848310156129705760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128a1908261379e565b6128ab878a61379e565b6128b591906138a4565b6128bf91906138e6565b905073ffffffffffffffffffffffffffffffffffffffff8616612918576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f9565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f9565b61297a858461379e565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611912565b6000818310612a305781611912565b5090919050565b508054612a439061301b565b6000825580601f10612a53575050565b601f0160209004906000526020600020908101906114c191905b80821115612a815760008155600101612a6d565b5090565b600060208284031215612a9757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461191257600080fd5b803567ffffffffffffffff81168114612adf57600080fd5b919050565b600060208284031215612af657600080fd5b61191282612ac7565b6000815180845260005b81811015612b2557602081850181015186830182015201612b09565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006119126020830184612aff565b73ffffffffffffffffffffffffffffffffffffffff811681146114c157600080fd5b8035612adf81612b76565b600060208284031215612bb557600080fd5b813561191281612b76565b600060208284031215612bd257600080fd5b813567ffffffffffffffff811115612be957600080fd5b8201610100818503121561191257600080fd5b60008083601f840112612c0e57600080fd5b50813567ffffffffffffffff811115612c2657600080fd5b6020830191508360208260051b8501011115612c4157600080fd5b9250929050565b60008060008060408587031215612c5e57600080fd5b843567ffffffffffffffff80821115612c7657600080fd5b612c8288838901612bfc565b90965094506020870135915080821115612c9b57600080fd5b50612ca887828801612bfc565b95989497509550505050565b600080600060408486031215612cc957600080fd5b612cd284612ac7565b9250602084013567ffffffffffffffff80821115612cef57600080fd5b818601915086601f830112612d0357600080fd5b813581811115612d1257600080fd5b876020828501011115612d2457600080fd5b6020830194508093505050509250925092565b600060208284031215612d4957600080fd5b813567ffffffffffffffff811115612d6057600080fd5b820160a0818503121561191257600080fd5b602081526000825160406020840152612d8e6060840182612aff565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612dc98282612aff565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e2057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612dee565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e2057835167ffffffffffffffff1683529284019291840191600101612e48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612ec157612ec1612e6e565b60405290565b60405160c0810167ffffffffffffffff81118282101715612ec157612ec1612e6e565b80151581146114c157600080fd5b8035612adf81612eea565b80356fffffffffffffffffffffffffffffffff81168114612adf57600080fd5b600060608284031215612f3557600080fd5b6040516060810181811067ffffffffffffffff82111715612f5857612f58612e6e565b6040529050808235612f6981612eea565b8152612f7760208401612f03565b6020820152612f8860408401612f03565b60408201525092915050565b600080600060e08486031215612fa957600080fd5b612fb284612ac7565b9250612fc18560208601612f23565b9150612fd08560808601612f23565b90509250925092565b60008060208385031215612fec57600080fd5b823567ffffffffffffffff81111561300357600080fd5b61300f85828601612bfc565b90969095509350505050565b600181811c9082168061302f57607f821691505b602082108103613068577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f83011261307f57600080fd5b813567ffffffffffffffff8082111561309a5761309a612e6e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156130e0576130e0612e6e565b816040528381528660208588010111156130f957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561312c57600080fd5b613134612e9d565b823567ffffffffffffffff8082111561314c57600080fd5b6131583683870161306e565b835261316660208601612ac7565b602084015261317760408601612b98565b60408401526060850135606084015261319260808601612b98565b608084015260a08501359150808211156131ab57600080fd5b6131b73683870161306e565b60a084015260c08501359150808211156131d057600080fd5b6131dc3683870161306e565b60c084015260e08501359150808211156131f557600080fd5b506132023682860161306e565b60e08301525092915050565b601f821115611025576000816000526020600020601f850160051c810160208610156132375750805b601f850160051c820191505b8181101561325657828155600101613243565b505050505050565b67ffffffffffffffff83111561327657613276612e6e565b61328a83613284835461301b565b8361320e565b6000601f8411600181146132dc57600085156132a65750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611b7f565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561332b578685013582556020948501946001909201910161330b565b5086821015613366577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b60408152600061338b6040830186612aff565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a082360312156133ee57600080fd5b60405160a0810167ffffffffffffffff828210818311171561341257613412612e6e565b81604052843591508082111561342757600080fd5b506134343682860161306e565b82525061344360208401612ac7565b6020820152604083013561345681612b76565b604082015260608381013590820152608083013561347381612b76565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126134e157600080fd5b9190910192915050565b600061014082360312156134fe57600080fd5b613506612ec7565b61350f83612ac7565b815261351d60208401612ef8565b6020820152604083013567ffffffffffffffff8082111561353d57600080fd5b6135493683870161306e565b6040840152606085013591508082111561356257600080fd5b5061356f3682860161306e565b6060830152506135823660808501612f23565b60808201526135943660e08501612f23565b60a082015292915050565b815167ffffffffffffffff8111156135b9576135b9612e6e565b6135cd816135c7845461301b565b8461320e565b602080601f83116001811461362057600084156135ea5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613256565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561366d5788860151825594840194600190910190840161364e565b50858210156136a957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526136dd81840187612aff565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061371b9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612dc9565b60006020828403121561376457600080fd5b815161191281612eea565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f3576105f361376f565b67ffffffffffffffff8416815260e081016137fd60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612383565b606081016105f382848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561388257600080fd5b815161191281612b76565b80820281158282048414176105f3576105f361376f565b808201808211156105f3576105f361376f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261391c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b506040516200460d3803806200460d8339810160408190526200003591620004f0565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f816200014b565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0385811660805282811660c05260ff851660a052600480546001600160a01b031916918316919091179055825115801560e0526200013b576040805160008152602081019091526200013b9084620001c5565b5050505050505050505062000669565b336001600160a01b038216036200017557604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e051620001e6576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002715760008382815181106200020a576200020a6200061b565b602090810291909101015190506200022460028262000322565b1562000267576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620001e9565b5060005b81518110156200031d5760008282815181106200029657620002966200061b565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002c2575062000314565b620002cf60028262000342565b1562000312576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000275565b505050565b600062000339836001600160a01b03841662000359565b90505b92915050565b600062000339836001600160a01b0384166200045d565b60008181526001830160205260408120548015620004525760006200038060018362000631565b8554909150600090620003969060019062000631565b905080821462000402576000866000018281548110620003ba57620003ba6200061b565b9060005260206000200154905080876000018481548110620003e057620003e06200061b565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000416576200041662000653565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200033c565b60009150506200033c565b6000818152600183016020526040812054620004a6575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200033c565b5060006200033c565b6001600160a01b0381168114620004c557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620004eb81620004af565b919050565b600080600080600060a086880312156200050957600080fd5b85516200051681620004af565b8095505060208087015160ff811681146200053057600080fd5b60408801519095506001600160401b03808211156200054e57600080fd5b818901915089601f8301126200056357600080fd5b815181811115620005785762000578620004c8565b8060051b604051601f19603f83011681018181108582111715620005a057620005a0620004c8565b60405291825284820192508381018501918c831115620005bf57600080fd5b938501935b82851015620005e857620005d885620004de565b84529385019392850192620005c4565b809850505050505050620005ff60608701620004de565b91506200060f60808701620004de565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b818103818111156200033c57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e051613f016200070c6000396000818161054f01528181611c5b01526126a60152600081816105290152818161189f0152611f470152600081816102e001528181610ba901528181611a4801528181611b0201528181611b3601528181611b670152611bae0152600081816102470152818161029c01528181610708015281816120c40152818161263c01526128910152613f016000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610527578063e0351e131461054d578063e8a1da1714610573578063f2fde38b1461058657600080fd5b8063c0d78655146104d9578063c4bffe2b146104ec578063c75eea9c14610501578063cf7401f31461051457600080fd5b8063acfecf91116100de578063acfecf9114610426578063af58d59f14610439578063b0f479a1146104a8578063b7946580146104c657600080fd5b80639a4575b9146103d1578063a42a7b8b146103f1578063a7cd63b71461041157600080fd5b806354c8a4f31161017157806379ba50971161014b57806379ba5097146103855780637d54534e1461038d5780638926f54f146103a05780638da5cb5b146103b357600080fd5b806354c8a4f31461033f57806362ddd3c4146103545780636d3d1a581461036757600080fd5b8063240028e8116101ad578063240028e81461028c57806324f65ee7146102d9578063390775371461030a5780634c5ef0ed1461032c57600080fd5b806301ffc9a7146101d4578063181f5a77146101fc57806321df0da714610245575b600080fd5b6101e76101e2366004613051565b610599565b60405190151581526020015b60405180910390f35b6102386040518060400160405280601781526020017f4275726e4d696e74546f6b656e506f6f6c20312e352e3100000000000000000081525081565b6040516101f391906130f7565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e761029a36600461312c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f3565b61031d610318366004613149565b61067e565b604051905181526020016101f3565b6101e761033a3660046131a2565b61084d565b61035261034d366004613271565b610897565b005b6103526103623660046131a2565b610912565b60095473ffffffffffffffffffffffffffffffffffffffff16610267565b6103526109af565b61035261039b36600461312c565b610a7d565b6101e76103ae3660046132dd565b610afe565b60015473ffffffffffffffffffffffffffffffffffffffff16610267565b6103e46103df3660046132f8565b610b15565b6040516101f39190613333565b6104046103ff3660046132dd565b610bee565b6040516101f3919061338a565b610419610d59565b6040516101f3919061340c565b6103526104343660046131a2565b610d6a565b61044c6104473660046132dd565b610e82565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610267565b6102386104d43660046132dd565b610f57565b6103526104e736600461312c565b611007565b6104f46110e2565b6040516101f39190613466565b61044c61050f3660046132dd565b61119a565b6103526105223660046135ee565b61126c565b7f0000000000000000000000000000000000000000000000000000000000000000610267565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b610352610581366004613271565b6112f0565b61035261059436600461312c565b611802565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061062c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061067857507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60408051602081019091526000815261069682611816565b60006106ef60608401356106ea6106b060c0870187613633565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3a92505050565b611afe565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f1961073d606086016040870161312c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107aa57600080fd5b505af11580156107be573d6000803e3d6000fd5b506107d392505050606084016040850161312c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161083191815260200190565b60405180910390a3604080516020810190915290815292915050565b600061088f8383604051610862929190613698565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611bee565b949350505050565b61089f611c06565b61090c84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611c5992505050565b50505050565b61091a611c06565b61092383610afe565b61096a576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109aa8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e0f92505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a00576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a85611c06565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610678600567ffffffffffffffff8416611bee565b6040805180820190915260608082526020820152610b3282611f09565b610b3f8260600135612095565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b998460200160208101906104d491906132dd565b8152602001610be66040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610c1790600501612131565b90506000815167ffffffffffffffff811115610c3557610c356134a8565b604051908082528060200260200182016040528015610c6857816020015b6060815260200190600190039081610c535790505b50905060005b8251811015610d515760086000848381518110610c8d57610c8d6136a8565b602002602001015181526020019081526020016000208054610cae906136d7565b80601f0160208091040260200160405190810160405280929190818152602001828054610cda906136d7565b8015610d275780601f10610cfc57610100808354040283529160200191610d27565b820191906000526020600020905b815481529060010190602001808311610d0a57829003601f168201915b5050505050828281518110610d3e57610d3e6136a8565b6020908102919091010152600101610c6e565b509392505050565b6060610d656002612131565b905090565b610d72611c06565b610d7b83610afe565b610dbd576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610961565b610dfd8282604051610dd0929190613698565b604080519182900390912067ffffffffffffffff861660009081526007602052919091206005019061213e565b610e39578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161096193929190613773565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610e75929190613797565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526106789061214a565b67ffffffffffffffff81166000908152600760205260409020600401805460609190610f82906136d7565b80601f0160208091040260200160405190810160405280929190818152602001828054610fae906136d7565b8015610ffb5780601f10610fd057610100808354040283529160200191610ffb565b820191906000526020600020905b815481529060010190602001808311610fde57829003601f168201915b50505050509050919050565b61100f611c06565b73ffffffffffffffffffffffffffffffffffffffff811661105c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110f06005612131565b90506000815167ffffffffffffffff81111561110e5761110e6134a8565b604051908082528060200260200182016040528015611137578160200160208202803683370190505b50905060005b825181101561119357828181518110611158576111586136a8565b6020026020010151828281518110611172576111726136a8565b67ffffffffffffffff9092166020928302919091019091015260010161113d565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526106789061214a565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906112ac575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156112e5576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b6109aa8383836121fc565b6112f8611c06565b60005b838110156114e5576000858583818110611317576113176136a8565b905060200201602081019061132c91906132dd565b9050611343600567ffffffffffffffff831661213e565b611385576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b67ffffffffffffffff811660009081526007602052604081206113aa90600501612131565b905060005b81518110156114165761140d8282815181106113cd576113cd6136a8565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161213e90919063ffffffff16565b506001016113af565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff0000000000000000000000000000000000000000009081168255600182018390556002820180549091169055600381018290559061147f6004830182612fe4565b6005820160008181611491828261301e565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916945060200192506114d3915050565b60405180910390a150506001016112fb565b5060005b818110156117fb576000838383818110611505576115056136a8565b905060200281019061151791906137ab565b61152090613877565b9050611531816060015160006122e6565b611540816080015160006122e6565b80604001515160000361157f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115979060059067ffffffffffffffff16612423565b6115dc5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610961565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a90910299909316171790941695909517909255909202909117600382015590820151600482019061175f90826139ee565b5060005b8260200151518110156117a35761179b83600001518460200151838151811061178e5761178e6136a8565b6020026020010151611e0f565b600101611763565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516117e99493929190613b08565b60405180910390a150506001016114e9565b5050505050565b61180a611c06565b6118138161242f565b50565b61182961029a60a083016080840161312c565b6118885761183d60a082016080830161312c565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610961565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6118d460408401602085016132dd565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119699190613ba1565b156119a0576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119b86119b360408301602084016132dd565b6124f3565b6119d86119cb60408301602084016132dd565b61033a60a0840184613633565b611a1d576119e960a0820182613633565b6040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610961929190613797565b611813611a3060408301602084016132dd565b8260600135612619565b60008151600003611a6c57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611aa957816040517f953576f700000000000000000000000000000000000000000000000000000000815260040161096191906130f7565b600082806020019051810190611abf9190613bbe565b905060ff81111561067857826040517f953576f700000000000000000000000000000000000000000000000000000000815260040161096191906130f7565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611b34575081610678565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611ba857611b8c7f000000000000000000000000000000000000000000000000000000000000000083613c06565b611b9790600a613d3f565b611ba19084613d4e565b9050610678565b611bd2827f0000000000000000000000000000000000000000000000000000000000000000613c06565b611bdd90600a613d3f565b611be79084613d89565b9392505050565b60008181526001830160205260408120541515611be7565b60015473ffffffffffffffffffffffffffffffffffffffff163314611c57576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611cb0576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611d46576000838281518110611cd057611cd06136a8565b60200260200101519050611cee81600261266090919063ffffffff16565b15611d3d5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611cb3565b5060005b81518110156109aa576000828281518110611d6757611d676136a8565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611dab5750611e07565b611db6600282612682565b15611e055760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611d4a565b8051600003611e4a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff8416600090815260079092526040909120611e7c9060050182612423565b611eb65782826040517f393b8ad2000000000000000000000000000000000000000000000000000000008152600401610961929190613da0565b6000818152600860205260409020611ece83826139ee565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610e7591906130f7565b611f1c61029a60a083016080840161312c565b611f305761183d60a082016080830161312c565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611f7c60408401602085016132dd565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611fed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120119190613ba1565b15612048576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61206061205b606083016040840161312c565b6126a4565b61207861207360408301602084016132dd565b612723565b61181361208b60408301602084016132dd565b8260600135612871565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b15801561211d57600080fd5b505af11580156117fb573d6000803e3d6000fd5b60606000611be7836128b5565b6000611be78383612910565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526121d882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426121bc9190613dc3565b85608001516fffffffffffffffffffffffffffffffff16612a03565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61220583610afe565b612247576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610961565b6122528260006122e6565b67ffffffffffffffff831660009081526007602052604090206122759083612a2b565b6122808160006122e6565b67ffffffffffffffff831660009081526007602052604090206122a69060020182612a2b565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516122d993929190613dd6565b60405180910390a1505050565b8151156123b15781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061233c575060408201516fffffffffffffffffffffffffffffffff16155b1561237557816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016109619190613e59565b80156123ad576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff161515806123ea575060208201516fffffffffffffffffffffffffffffffff1615155b156123ad57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016109619190613e59565b6000611be78383612bcd565b3373ffffffffffffffffffffffffffffffffffffffff82160361247e576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6124fc81610afe565b61253e576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156125bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125e19190613ba1565b611813576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b67ffffffffffffffff821660009081526007602052604090206123ad90600201827f0000000000000000000000000000000000000000000000000000000000000000612c1c565b6000611be78373ffffffffffffffffffffffffffffffffffffffff8416612910565b6000611be78373ffffffffffffffffffffffffffffffffffffffff8416612bcd565b7f000000000000000000000000000000000000000000000000000000000000000015611813576126d5600282612f9f565b611813576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610961565b61272c81610afe565b61276e576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610961565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156127e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280b9190613e95565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611813576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610961565b67ffffffffffffffff821660009081526007602052604090206123ad90827f0000000000000000000000000000000000000000000000000000000000000000612c1c565b606081600001805480602002602001604051908101604052809291908181526020018280548015610ffb57602002820191906000526020600020905b8154815260200190600101908083116128f15750505050509050919050565b600081815260018301602052604081205480156129f9576000612934600183613dc3565b855490915060009061294890600190613dc3565b90508082146129ad576000866000018281548110612968576129686136a8565b906000526020600020015490508087600001848154811061298b5761298b6136a8565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806129be576129be613eb2565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610678565b6000915050610678565b6000612a2285612a138486613d89565b612a1d9087613ee1565b612fce565b95945050505050565b8154600090612a5490700100000000000000000000000000000000900463ffffffff1642613dc3565b90508015612af65760018301548354612a9c916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612a03565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612b1c916fffffffffffffffffffffffffffffffff9081169116612fce565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906122d9908490613e59565b6000818152600183016020526040812054612c1457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610678565b506000610678565b825474010000000000000000000000000000000000000000900460ff161580612c43575081155b15612c4d57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612c9390700100000000000000000000000000000000900463ffffffff1642613dc3565b90508015612d535781831115612cd5576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612d0f9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612a03565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612e0a5773ffffffffffffffffffffffffffffffffffffffff8416612db2576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610961565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610961565b84831015612f1d5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612e4e9082613dc3565b612e58878a613dc3565b612e629190613ee1565b612e6c9190613d4e565b905073ffffffffffffffffffffffffffffffffffffffff8616612ec5576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610961565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610961565b612f278584613dc3565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611be7565b6000818310612fdd5781611be7565b5090919050565b508054612ff0906136d7565b6000825580601f10613000575050565b601f0160209004906000526020600020908101906118139190613038565b508054600082559060005260206000209081019061181391905b5b8082111561304d5760008155600101613039565b5090565b60006020828403121561306357600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611be757600080fd5b6000815180845260005b818110156130b95760208185018101518683018201520161309d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611be76020830184613093565b73ffffffffffffffffffffffffffffffffffffffff8116811461181357600080fd5b60006020828403121561313e57600080fd5b8135611be78161310a565b60006020828403121561315b57600080fd5b813567ffffffffffffffff81111561317257600080fd5b82016101008185031215611be757600080fd5b803567ffffffffffffffff8116811461319d57600080fd5b919050565b6000806000604084860312156131b757600080fd5b6131c084613185565b9250602084013567ffffffffffffffff808211156131dd57600080fd5b818601915086601f8301126131f157600080fd5b81358181111561320057600080fd5b87602082850101111561321257600080fd5b6020830194508093505050509250925092565b60008083601f84011261323757600080fd5b50813567ffffffffffffffff81111561324f57600080fd5b6020830191508360208260051b850101111561326a57600080fd5b9250929050565b6000806000806040858703121561328757600080fd5b843567ffffffffffffffff8082111561329f57600080fd5b6132ab88838901613225565b909650945060208701359150808211156132c457600080fd5b506132d187828801613225565b95989497509550505050565b6000602082840312156132ef57600080fd5b611be782613185565b60006020828403121561330a57600080fd5b813567ffffffffffffffff81111561332157600080fd5b820160a08185031215611be757600080fd5b60208152600082516040602084015261334f6060840182613093565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612a228282613093565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156133ff577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526133ed858351613093565b945092850192908501906001016133b3565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561345a57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613428565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561345a57835167ffffffffffffffff1683529284019291840191600101613482565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156134fa576134fa6134a8565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613547576135476134a8565b604052919050565b801515811461181357600080fd5b80356fffffffffffffffffffffffffffffffff8116811461319d57600080fd5b60006060828403121561358f57600080fd5b6040516060810181811067ffffffffffffffff821117156135b2576135b26134a8565b60405290508082356135c38161354f565b81526135d16020840161355d565b60208201526135e26040840161355d565b60408201525092915050565b600080600060e0848603121561360357600080fd5b61360c84613185565b925061361b856020860161357d565b915061362a856080860161357d565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261366857600080fd5b83018035915067ffffffffffffffff82111561368357600080fd5b60200191503681900382131561326a57600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c908216806136eb57607f821691505b602082108103613724577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612a2260408301848661372a565b60208152600061088f60208301848661372a565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181126137df57600080fd5b9190910192915050565b600082601f8301126137fa57600080fd5b813567ffffffffffffffff811115613814576138146134a8565b61384560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613500565b81815284602083860101111561385a57600080fd5b816020850160208301376000918101602001919091529392505050565b6000610120823603121561388a57600080fd5b6138926134d7565b61389b83613185565b815260208084013567ffffffffffffffff808211156138b957600080fd5b9085019036601f8301126138cc57600080fd5b8135818111156138de576138de6134a8565b8060051b6138ed858201613500565b918252838101850191858101903684111561390757600080fd5b86860192505b83831015613943578235858111156139255760008081fd5b6139333689838a01016137e9565b835250918601919086019061390d565b808789015250505050604086013592508083111561396057600080fd5b505061396e368286016137e9565b604083015250613981366060850161357d565b60608201526139933660c0850161357d565b608082015292915050565b601f8211156109aa576000816000526020600020601f850160051c810160208610156139c75750805b601f850160051c820191505b818110156139e6578281556001016139d3565b505050505050565b815167ffffffffffffffff811115613a0857613a086134a8565b613a1c81613a1684546136d7565b8461399e565b602080601f831160018114613a6f5760008415613a395750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139e6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613abc57888601518255948401946001909101908401613a9d565b5085821015613af857878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613b2c81840187613093565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613b6a9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612a22565b600060208284031215613bb357600080fd5b8151611be78161354f565b600060208284031215613bd057600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561067857610678613bd7565b600181815b80851115613c7857817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613c5e57613c5e613bd7565b80851615613c6b57918102915b93841c9390800290613c24565b509250929050565b600082613c8f57506001610678565b81613c9c57506000610678565b8160018114613cb25760028114613cbc57613cd8565b6001915050610678565b60ff841115613ccd57613ccd613bd7565b50506001821b610678565b5060208310610133831016604e8410600b8410161715613cfb575081810a610678565b613d058383613c1f565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613d3757613d37613bd7565b029392505050565b6000611be760ff841683613c80565b600082613d84577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761067857610678613bd7565b67ffffffffffffffff8316815260406020820152600061088f6040830184613093565b8181038181111561067857610678613bd7565b67ffffffffffffffff8416815260e08101613e2260208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c083015261088f565b6060810161067882848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215613ea757600080fd5b8151611be78161310a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561067857610678613bd756fea164736f6c6343000818000a", } var BurnMintTokenPoolABI = BurnMintTokenPoolMetaData.ABI var BurnMintTokenPoolBin = BurnMintTokenPoolMetaData.Bin -func DeployBurnMintTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, rmnProxy common.Address, router common.Address) (common.Address, *types.Transaction, *BurnMintTokenPool, error) { +func DeployBurnMintTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, localTokenDecimals uint8, allowlist []common.Address, rmnProxy common.Address, router common.Address) (common.Address, *types.Transaction, *BurnMintTokenPool, error) { parsed, err := BurnMintTokenPoolMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -99,7 +98,7 @@ func DeployBurnMintTokenPool(auth *bind.TransactOpts, backend bind.ContractBacke return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnMintTokenPoolBin), backend, token, allowlist, rmnProxy, router) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnMintTokenPoolBin), backend, token, localTokenDecimals, allowlist, rmnProxy, router) if err != nil { return common.Address{}, nil, nil, err } @@ -332,26 +331,26 @@ func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetRateLimitAdmin() (c return _BurnMintTokenPool.Contract.GetRateLimitAdmin(&_BurnMintTokenPool.CallOpts) } -func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetRemotePools(opts *bind.CallOpts, remoteChainSelector uint64) ([][]byte, error) { var out []interface{} - err := _BurnMintTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + err := _BurnMintTokenPool.contract.Call(opts, &out, "getRemotePools", remoteChainSelector) if err != nil { - return *new([]byte), err + return *new([][]byte), err } - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + out0 := *abi.ConvertType(out[0], new([][]byte)).(*[][]byte) return out0, err } -func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { - return _BurnMintTokenPool.Contract.GetRemotePool(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetRemotePools(remoteChainSelector uint64) ([][]byte, error) { + return _BurnMintTokenPool.Contract.GetRemotePools(&_BurnMintTokenPool.CallOpts, remoteChainSelector) } -func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { - return _BurnMintTokenPool.Contract.GetRemotePool(&_BurnMintTokenPool.CallOpts, remoteChainSelector) +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetRemotePools(remoteChainSelector uint64) ([][]byte, error) { + return _BurnMintTokenPool.Contract.GetRemotePools(&_BurnMintTokenPool.CallOpts, remoteChainSelector) } func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { @@ -464,6 +463,50 @@ func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetToken() (common.Add return _BurnMintTokenPool.Contract.GetToken(&_BurnMintTokenPool.CallOpts) } +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) GetTokenDecimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "getTokenDecimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) GetTokenDecimals() (uint8, error) { + return _BurnMintTokenPool.Contract.GetTokenDecimals(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) GetTokenDecimals() (uint8, error) { + return _BurnMintTokenPool.Contract.GetTokenDecimals(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) IsRemotePool(opts *bind.CallOpts, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "isRemotePool", remoteChainSelector, remotePoolAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) IsRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + return _BurnMintTokenPool.Contract.IsRemotePool(&_BurnMintTokenPool.CallOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) IsRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + return _BurnMintTokenPool.Contract.IsRemotePool(&_BurnMintTokenPool.CallOpts, remoteChainSelector, remotePoolAddress) +} + func (_BurnMintTokenPool *BurnMintTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { var out []interface{} err := _BurnMintTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) @@ -586,6 +629,18 @@ func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) AcceptOwnership() return _BurnMintTokenPool.Contract.AcceptOwnership(&_BurnMintTokenPool.TransactOpts) } +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) AddRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "addRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) AddRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.AddRemotePool(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) AddRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.AddRemotePool(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { return _BurnMintTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) } @@ -598,16 +653,16 @@ func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ApplyAllowListUpda return _BurnMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnMintTokenPool.TransactOpts, removes, adds) } -func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _BurnMintTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "applyChainUpdates", remoteChainSelectorsToRemove, chainsToAdd) } -func (_BurnMintTokenPool *BurnMintTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _BurnMintTokenPool.Contract.ApplyChainUpdates(&_BurnMintTokenPool.TransactOpts, chains) +func (_BurnMintTokenPool *BurnMintTokenPoolSession) ApplyChainUpdates(remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyChainUpdates(&_BurnMintTokenPool.TransactOpts, remoteChainSelectorsToRemove, chainsToAdd) } -func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _BurnMintTokenPool.Contract.ApplyChainUpdates(&_BurnMintTokenPool.TransactOpts, chains) +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ApplyChainUpdates(remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.ApplyChainUpdates(&_BurnMintTokenPool.TransactOpts, remoteChainSelectorsToRemove, chainsToAdd) } func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { @@ -634,6 +689,18 @@ func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) ReleaseOrMint(rele return _BurnMintTokenPool.Contract.ReleaseOrMint(&_BurnMintTokenPool.TransactOpts, releaseOrMintIn) } +func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) RemoveRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.contract.Transact(opts, "removeRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) RemoveRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.RemoveRemotePool(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) RemoveRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnMintTokenPool.Contract.RemoveRemotePool(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { return _BurnMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) } @@ -658,18 +725,6 @@ func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetRateLimitAdmin( return _BurnMintTokenPool.Contract.SetRateLimitAdmin(&_BurnMintTokenPool.TransactOpts, rateLimitAdmin) } -func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _BurnMintTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) -} - -func (_BurnMintTokenPool *BurnMintTokenPoolSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _BurnMintTokenPool.Contract.SetRemotePool(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) -} - -func (_BurnMintTokenPool *BurnMintTokenPoolTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _BurnMintTokenPool.Contract.SetRemotePool(&_BurnMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) -} - func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { return _BurnMintTokenPool.contract.Transact(opts, "setRouter", newRouter) } @@ -2320,8 +2375,136 @@ func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseReleased(log types.Log return event, nil } -type BurnMintTokenPoolRemotePoolSetIterator struct { - Event *BurnMintTokenPoolRemotePoolSet +type BurnMintTokenPoolRemotePoolAddedIterator struct { + Event *BurnMintTokenPoolRemotePoolAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnMintTokenPoolRemotePoolAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolRemotePoolAdded) + 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 + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnMintTokenPoolRemotePoolAdded) + 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() + } +} + +func (it *BurnMintTokenPoolRemotePoolAddedIterator) Error() error { + return it.fail +} + +func (it *BurnMintTokenPoolRemotePoolAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnMintTokenPoolRemotePoolAdded struct { + RemoteChainSelector uint64 + RemotePoolAddress []byte + Raw types.Log +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterRemotePoolAdded(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnMintTokenPoolRemotePoolAddedIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "RemotePoolAdded", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &BurnMintTokenPoolRemotePoolAddedIterator{contract: _BurnMintTokenPool.contract, event: "RemotePoolAdded", logs: logs, sub: sub}, nil +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchRemotePoolAdded(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolRemotePoolAdded, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "RemotePoolAdded", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnMintTokenPoolRemotePoolAdded) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "RemotePoolAdded", 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 +} + +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseRemotePoolAdded(log types.Log) (*BurnMintTokenPoolRemotePoolAdded, error) { + event := new(BurnMintTokenPoolRemotePoolAdded) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "RemotePoolAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnMintTokenPoolRemotePoolRemovedIterator struct { + Event *BurnMintTokenPoolRemotePoolRemoved contract *bind.BoundContract event string @@ -2332,7 +2515,7 @@ type BurnMintTokenPoolRemotePoolSetIterator struct { fail error } -func (it *BurnMintTokenPoolRemotePoolSetIterator) Next() bool { +func (it *BurnMintTokenPoolRemotePoolRemovedIterator) Next() bool { if it.fail != nil { return false @@ -2341,7 +2524,7 @@ func (it *BurnMintTokenPoolRemotePoolSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(BurnMintTokenPoolRemotePoolSet) + it.Event = new(BurnMintTokenPoolRemotePoolRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2356,7 +2539,7 @@ func (it *BurnMintTokenPoolRemotePoolSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(BurnMintTokenPoolRemotePoolSet) + it.Event = new(BurnMintTokenPoolRemotePoolRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2371,44 +2554,43 @@ func (it *BurnMintTokenPoolRemotePoolSetIterator) Next() bool { } } -func (it *BurnMintTokenPoolRemotePoolSetIterator) Error() error { +func (it *BurnMintTokenPoolRemotePoolRemovedIterator) Error() error { return it.fail } -func (it *BurnMintTokenPoolRemotePoolSetIterator) Close() error { +func (it *BurnMintTokenPoolRemotePoolRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -type BurnMintTokenPoolRemotePoolSet struct { +type BurnMintTokenPoolRemotePoolRemoved struct { RemoteChainSelector uint64 - PreviousPoolAddress []byte RemotePoolAddress []byte Raw types.Log } -func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnMintTokenPoolRemotePoolSetIterator, error) { +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) FilterRemotePoolRemoved(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnMintTokenPoolRemotePoolRemovedIterator, error) { var remoteChainSelectorRule []interface{} for _, remoteChainSelectorItem := range remoteChainSelector { remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + logs, sub, err := _BurnMintTokenPool.contract.FilterLogs(opts, "RemotePoolRemoved", remoteChainSelectorRule) if err != nil { return nil, err } - return &BurnMintTokenPoolRemotePoolSetIterator{contract: _BurnMintTokenPool.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil + return &BurnMintTokenPoolRemotePoolRemovedIterator{contract: _BurnMintTokenPool.contract, event: "RemotePoolRemoved", logs: logs, sub: sub}, nil } -func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchRemotePoolRemoved(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolRemotePoolRemoved, remoteChainSelector []uint64) (event.Subscription, error) { var remoteChainSelectorRule []interface{} for _, remoteChainSelectorItem := range remoteChainSelector { remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + logs, sub, err := _BurnMintTokenPool.contract.WatchLogs(opts, "RemotePoolRemoved", remoteChainSelectorRule) if err != nil { return nil, err } @@ -2418,8 +2600,8 @@ func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchRemotePoolSet(opts *bi select { case log := <-logs: - event := new(BurnMintTokenPoolRemotePoolSet) - if err := _BurnMintTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + event := new(BurnMintTokenPoolRemotePoolRemoved) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "RemotePoolRemoved", log); err != nil { return err } event.Raw = log @@ -2440,9 +2622,9 @@ func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) WatchRemotePoolSet(opts *bi }), nil } -func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseRemotePoolSet(log types.Log) (*BurnMintTokenPoolRemotePoolSet, error) { - event := new(BurnMintTokenPoolRemotePoolSet) - if err := _BurnMintTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { +func (_BurnMintTokenPool *BurnMintTokenPoolFilterer) ParseRemotePoolRemoved(log types.Log) (*BurnMintTokenPoolRemotePoolRemoved, error) { + event := new(BurnMintTokenPoolRemotePoolRemoved) + if err := _BurnMintTokenPool.contract.UnpackLog(event, "RemotePoolRemoved", log); err != nil { return nil, err } event.Raw = log @@ -2712,8 +2894,10 @@ func (_BurnMintTokenPool *BurnMintTokenPool) ParseLog(log types.Log) (generated. return _BurnMintTokenPool.ParseRateLimitAdminSet(log) case _BurnMintTokenPool.abi.Events["Released"].ID: return _BurnMintTokenPool.ParseReleased(log) - case _BurnMintTokenPool.abi.Events["RemotePoolSet"].ID: - return _BurnMintTokenPool.ParseRemotePoolSet(log) + case _BurnMintTokenPool.abi.Events["RemotePoolAdded"].ID: + return _BurnMintTokenPool.ParseRemotePoolAdded(log) + case _BurnMintTokenPool.abi.Events["RemotePoolRemoved"].ID: + return _BurnMintTokenPool.ParseRemotePoolRemoved(log) case _BurnMintTokenPool.abi.Events["RouterUpdated"].ID: return _BurnMintTokenPool.ParseRouterUpdated(log) case _BurnMintTokenPool.abi.Events["TokensConsumed"].ID: @@ -2776,8 +2960,12 @@ func (BurnMintTokenPoolReleased) Topic() common.Hash { return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") } -func (BurnMintTokenPoolRemotePoolSet) Topic() common.Hash { - return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +func (BurnMintTokenPoolRemotePoolAdded) Topic() common.Hash { + return common.HexToHash("0x7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea") +} + +func (BurnMintTokenPoolRemotePoolRemoved) Topic() common.Hash { + return common.HexToHash("0x52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d76") } func (BurnMintTokenPoolRouterUpdated) Topic() common.Hash { @@ -2803,7 +2991,7 @@ type BurnMintTokenPoolInterface interface { GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) - GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + GetRemotePools(opts *bind.CallOpts, remoteChainSelector uint64) ([][]byte, error) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) @@ -2815,6 +3003,10 @@ type BurnMintTokenPoolInterface interface { GetToken(opts *bind.CallOpts) (common.Address, error) + GetTokenDecimals(opts *bind.CallOpts) (uint8, error) + + IsRemotePool(opts *bind.CallOpts, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) @@ -2827,20 +3019,22 @@ type BurnMintTokenPoolInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + AddRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) - ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + ApplyChainUpdates(opts *bind.TransactOpts, remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + RemoveRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) - SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) - SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) @@ -2923,11 +3117,17 @@ type BurnMintTokenPoolInterface interface { ParseReleased(log types.Log) (*BurnMintTokenPoolReleased, error) - FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnMintTokenPoolRemotePoolSetIterator, error) + FilterRemotePoolAdded(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnMintTokenPoolRemotePoolAddedIterator, error) + + WatchRemotePoolAdded(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolRemotePoolAdded, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolAdded(log types.Log) (*BurnMintTokenPoolRemotePoolAdded, error) + + FilterRemotePoolRemoved(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnMintTokenPoolRemotePoolRemovedIterator, error) - WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + WatchRemotePoolRemoved(opts *bind.WatchOpts, sink chan<- *BurnMintTokenPoolRemotePoolRemoved, remoteChainSelector []uint64) (event.Subscription, error) - ParseRemotePoolSet(log types.Log) (*BurnMintTokenPoolRemotePoolSet, error) + ParseRemotePoolRemoved(log types.Log) (*BurnMintTokenPoolRemotePoolRemoved, error) FilterRouterUpdated(opts *bind.FilterOpts) (*BurnMintTokenPoolRouterUpdatedIterator, error) diff --git a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go index 22409787fd8..2343828e892 100644 --- a/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_with_from_mint_token_pool/burn_with_from_mint_token_pool.go @@ -74,23 +74,22 @@ type RateLimiterTokenBucket struct { type TokenPoolChainUpdate struct { RemoteChainSelector uint64 - Allowed bool - RemotePoolAddress []byte + RemotePoolAddresses [][]byte RemoteTokenAddress []byte OutboundRateLimiterConfig RateLimiterConfig InboundRateLimiterConfig RateLimiterConfig } var BurnWithFromMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620044473803806200444783398101604081905262000034916200085d565b83838383336000816200005a57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008d576200008d8162000159565b50506001600160a01b0384161580620000ad57506001600160a01b038116155b80620000c057506001600160a01b038216155b15620000df576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200013257604080516000815260208101909152620001329084620001d3565b506200014f925050506001600160a01b0385163060001962000330565b5050505062000a99565b336001600160a01b038216036200018357604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620001f4576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200027f5760008382815181106200021857620002186200096d565b602090810291909101015190506200023260028262000416565b1562000275576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620001f7565b5060005b81518110156200032b576000828281518110620002a457620002a46200096d565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002d0575062000322565b620002dd60028262000436565b1562000320576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000283565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000382573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a8919062000983565b620003b49190620009b3565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915291925062000410918691906200044d16565b50505050565b60006200042d836001600160a01b03841662000522565b90505b92915050565b60006200042d836001600160a01b03841662000626565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200049c906001600160a01b03851690849062000678565b8051909150156200032b5780806020019051810190620004bd9190620009c9565b6200032b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b600081815260018301602052604081205480156200061b57600062000549600183620009f4565b85549091506000906200055f90600190620009f4565b9050808214620005cb5760008660000182815481106200058357620005836200096d565b9060005260206000200154905080876000018481548110620005a957620005a96200096d565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620005df57620005df62000a0a565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000430565b600091505062000430565b60008181526001830160205260408120546200066f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000430565b50600062000430565b606062000689848460008562000691565b949350505050565b606082471015620006f45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000519565b600080866001600160a01b0316858760405162000712919062000a46565b60006040518083038185875af1925050503d806000811462000751576040519150601f19603f3d011682016040523d82523d6000602084013e62000756565b606091505b5090925090506200076a8783838762000775565b979650505050505050565b60608315620007e9578251600003620007e1576001600160a01b0385163b620007e15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000519565b508162000689565b620006898383815115620008005781518083602001fd5b8060405162461bcd60e51b815260040162000519919062000a64565b6001600160a01b03811681146200083257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000858816200081c565b919050565b600080600080608085870312156200087457600080fd5b845162000881816200081c565b602086810151919550906001600160401b0380821115620008a157600080fd5b818801915088601f830112620008b657600080fd5b815181811115620008cb57620008cb62000835565b8060051b604051601f19603f83011681018181108582111715620008f357620008f362000835565b60405291825284820192508381018501918b8311156200091257600080fd5b938501935b828510156200093b576200092b856200084b565b8452938501939285019262000917565b80985050505050505062000952604086016200084b565b915062000962606086016200084b565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156200099657600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156200043057620004306200099d565b600060208284031215620009dc57600080fd5b81518015158114620009ed57600080fd5b9392505050565b818103818111156200043057620004306200099d565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000a3d57818101518382015260200162000a23565b50506000910152565b6000825162000a5a81846020870162000a20565b9190910192915050565b602081526000825180602084015262000a8581604085016020870162000a20565b601f01601f19169190910160400192915050565b60805160a05160c05161393162000b16600039600081816104da0152818161174701526120fa0152600081816104b4015281816115a801526119fd0152600081816102360152818161028b015281816106dd015281816114c80152818161191d01528181611b150152818161209001526122e501526139316000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80639a4575b9116100ee578063c4bffe2b11610097578063db6327dc11610071578063db6327dc1461049f578063dc0bd971146104b2578063e0351e13146104d8578063f2fde38b146104fe57600080fd5b8063c4bffe2b14610464578063c75eea9c14610479578063cf7401f31461048c57600080fd5b8063b0f479a1116100c8578063b0f479a114610420578063b79465801461043e578063c0d786551461045157600080fd5b80639a4575b91461037c578063a7cd63b71461039c578063af58d59f146103b157600080fd5b806354c8a4f31161015b57806379ba50971161013557806379ba5097146103305780637d54534e146103385780638926f54f1461034b5780638da5cb5b1461035e57600080fd5b806354c8a4f3146102ea5780636d3d1a58146102ff57806378a010b21461031d57600080fd5b806321df0da71161018c57806321df0da714610234578063240028e81461027b57806339077537146102c857600080fd5b806301ffc9a7146101b35780630a2fd493146101db578063181f5a77146101fb575b600080fd5b6101c66101c1366004612a88565b610511565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612ae7565b6105f6565b6040516101d29190612b66565b60408051808201909152601f81527f4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e300060208201526101ee565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b6101c6610289366004612ba6565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6102db6102d6366004612bc3565b6106a6565b604051905181526020016101d2565b6102fd6102f8366004612c4b565b61082c565b005b60085473ffffffffffffffffffffffffffffffffffffffff16610256565b6102fd61032b366004612cb7565b6108a7565b6102fd610a1b565b6102fd610346366004612ba6565b610ae9565b6101c6610359366004612ae7565b610b6a565b60015473ffffffffffffffffffffffffffffffffffffffff16610256565b61038f61038a366004612d3a565b610b81565b6040516101d29190612d75565b6103a4610c28565b6040516101d29190612dd5565b6103c46103bf366004612ae7565b610c39565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610256565b6101ee61044c366004612ae7565b610d0e565b6102fd61045f366004612ba6565b610d39565b61046c610e14565b6040516101d29190612e2f565b6103c4610487366004612ae7565b610ecc565b6102fd61049a366004612f97565b610f9e565b6102fd6104ad366004612fdc565b611027565b7f0000000000000000000000000000000000000000000000000000000000000000610256565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b6102fd61050c366004612ba6565b6114ad565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806105a457507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806105f057507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff811660009081526007602052604090206004018054606091906106219061301e565b80601f016020809104026020016040519081016040528092919081815260200182805461064d9061301e565b801561069a5780601f1061066f5761010080835404028352916020019161069a565b820191906000526020600020905b81548152906001019060200180831161067d57829003601f168201915b50505050509050919050565b6040805160208101909152600081526106c66106c18361311c565b6114c1565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f196107126060850160408601612ba6565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260608501356024820152604401600060405180830381600087803b15801561078257600080fd5b505af1158015610796573d6000803e3d6000fd5b506107ab925050506060830160408401612ba6565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0846060013560405161080d91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6108346116f2565b6108a18484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061174592505050565b50505050565b6108af6116f2565b6108b883610b6a565b6108ff576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b67ffffffffffffffff8316600090815260076020526040812060040180546109269061301e565b80601f01602080910402602001604051908101604052809291908181526020018280546109529061301e565b801561099f5780601f106109745761010080835404028352916020019161099f565b820191906000526020600020905b81548152906001019060200180831161098257829003601f168201915b5050505067ffffffffffffffff86166000908152600760205260409020919250506004016109ce838583613261565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610a0d9392919061337b565b60405180910390a250505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a6c576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610af16116f2565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b60006105f0600567ffffffffffffffff84166118fb565b6040805180820190915260608082526020820152610ba6610ba1836133df565b611916565b610bb38260600135611ae0565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610c0d84602001602081019061044c9190612ae7565b81526040805160208181019092526000815291015292915050565b6060610c346002611b89565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526105f090611b96565b67ffffffffffffffff811660009081526007602052604090206005018054606091906106219061301e565b610d416116f2565b73ffffffffffffffffffffffffffffffffffffffff8116610d8e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b60606000610e226005611b89565b90506000815167ffffffffffffffff811115610e4057610e40612e71565b604051908082528060200260200182016040528015610e69578160200160208202803683370190505b50905060005b8251811015610ec557828181518110610e8a57610e8a613481565b6020026020010151828281518110610ea457610ea4613481565b67ffffffffffffffff90921660209283029190910190910152600101610e6f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526105f090611b96565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590610fde575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15611017576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024016108f6565b611022838383611c48565b505050565b61102f6116f2565b60005b8181101561102257600083838381811061104e5761104e613481565b905060200281019061106091906134b0565b611069906134ee565b905061107e8160800151826020015115611d32565b6110918160a00151826020015115611d32565b80602001511561138d5780516110b39060059067ffffffffffffffff16611e6b565b6110f85780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f6565b604081015151158061110d5750606081015151155b15611144576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c1790911696151502959095179098559081015194015193811693169091029190911760038201559151909190600482019061132590826135a2565b506060820151600582019061133a90826135a2565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2955061138094939291906136bc565b60405180910390a16114a4565b80516113a59060059067ffffffffffffffff16611e77565b6113ea5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108f6565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114536004830182612a3a565b611461600583016000612a3a565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611032565b6114b56116f2565b6114be81611e83565b50565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146115565760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f6565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611604573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116289190613755565b1561165f576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166c8160200151611f47565b600061167b82602001516105f6565b905080516000148061169f575080805190602001208260a001518051906020012014155b156116dc578160a001516040517f24eb47e50000000000000000000000000000000000000000000000000000000081526004016108f69190612b66565b6116ee8260200151836060015161206d565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611743576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f000000000000000000000000000000000000000000000000000000000000000061179c576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118325760008382815181106117bc576117bc613481565b602002602001015190506117da8160026120b490919063ffffffff16565b156118295760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010161179f565b5060005b815181101561102257600082828151811061185357611853613481565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361189757506118f3565b6118a26002826120d6565b156118f15760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611836565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff9081169116146119ab5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016108f6565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611a59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a7d9190613755565b15611ab4576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ac181604001516120f8565b611ace8160200151612177565b6114be816020015182606001516122c5565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b158015611b6e57600080fd5b505af1158015611b82573d6000803e3d6000fd5b5050505050565b6060600061190f83612309565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c2482606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611c0891906137a1565b85608001516fffffffffffffffffffffffffffffffff16612364565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b611c5183610b6a565b611c93576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024016108f6565b611c9e826000611d32565b67ffffffffffffffff83166000908152600760205260409020611cc1908361238e565b611ccc816000611d32565b67ffffffffffffffff83166000908152600760205260409020611cf2906002018261238e565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b838383604051611d25939291906137b4565b60405180910390a1505050565b815115611df95781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580611d88575060408201516fffffffffffffffffffffffffffffffff16155b15611dc157816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016108f69190613837565b80156116ee576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff16151580611e32575060208201516fffffffffffffffffffffffffffffffff1615155b156116ee57816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016108f69190613837565b600061190f8383612530565b600061190f838361257f565b3373ffffffffffffffffffffffffffffffffffffffff821603611ed2576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b611f5081610b6a565b611f92576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f6565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612011573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120359190613755565b6114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f6565b67ffffffffffffffff821660009081526007602052604090206116ee90600201827f0000000000000000000000000000000000000000000000000000000000000000612672565b600061190f8373ffffffffffffffffffffffffffffffffffffffff841661257f565b600061190f8373ffffffffffffffffffffffffffffffffffffffff8416612530565b7f0000000000000000000000000000000000000000000000000000000000000000156114be576121296002826129f5565b6114be576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016108f6565b61218081610b6a565b6121c2576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff821660048201526024016108f6565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa15801561223b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225f9190613873565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146114be576040517f728fe07b0000000000000000000000000000000000000000000000000000000081523360048201526024016108f6565b67ffffffffffffffff821660009081526007602052604090206116ee90827f0000000000000000000000000000000000000000000000000000000000000000612672565b60608160000180548060200260200160405190810160405280929190818152602001828054801561069a57602002820191906000526020600020905b8154815260200190600101908083116123455750505050509050919050565b6000612383856123748486613890565b61237e90876138a7565b612a24565b90505b949350505050565b81546000906123b790700100000000000000000000000000000000900463ffffffff16426137a1565b9050801561245957600183015483546123ff916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612364565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461247f916fffffffffffffffffffffffffffffffff9081169116612a24565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611d25908490613837565b6000818152600183016020526040812054612577575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f0565b5060006105f0565b600081815260018301602052604081205480156126685760006125a36001836137a1565b85549091506000906125b7906001906137a1565b905080821461261c5760008660000182815481106125d7576125d7613481565b90600052602060002001549050808760000184815481106125fa576125fa613481565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061262d5761262d6138ba565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f0565b60009150506105f0565b825474010000000000000000000000000000000000000000900460ff161580612699575081155b156126a357505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906126e990700100000000000000000000000000000000900463ffffffff16426137a1565b905080156127a9578183111561272b576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546127659083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612364565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156128605773ffffffffffffffffffffffffffffffffffffffff8416612808576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016108f6565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016108f6565b848310156129735760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906128a490826137a1565b6128ae878a6137a1565b6128b891906138a7565b6128c291906138e9565b905073ffffffffffffffffffffffffffffffffffffffff861661291b576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016108f6565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016108f6565b61297d85846137a1565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561190f565b6000818310612a33578161190f565b5090919050565b508054612a469061301e565b6000825580601f10612a56575050565b601f0160209004906000526020600020908101906114be91905b80821115612a845760008155600101612a70565b5090565b600060208284031215612a9a57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461190f57600080fd5b803567ffffffffffffffff81168114612ae257600080fd5b919050565b600060208284031215612af957600080fd5b61190f82612aca565b6000815180845260005b81811015612b2857602081850181015186830182015201612b0c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061190f6020830184612b02565b73ffffffffffffffffffffffffffffffffffffffff811681146114be57600080fd5b8035612ae281612b79565b600060208284031215612bb857600080fd5b813561190f81612b79565b600060208284031215612bd557600080fd5b813567ffffffffffffffff811115612bec57600080fd5b8201610100818503121561190f57600080fd5b60008083601f840112612c1157600080fd5b50813567ffffffffffffffff811115612c2957600080fd5b6020830191508360208260051b8501011115612c4457600080fd5b9250929050565b60008060008060408587031215612c6157600080fd5b843567ffffffffffffffff80821115612c7957600080fd5b612c8588838901612bff565b90965094506020870135915080821115612c9e57600080fd5b50612cab87828801612bff565b95989497509550505050565b600080600060408486031215612ccc57600080fd5b612cd584612aca565b9250602084013567ffffffffffffffff80821115612cf257600080fd5b818601915086601f830112612d0657600080fd5b813581811115612d1557600080fd5b876020828501011115612d2757600080fd5b6020830194508093505050509250925092565b600060208284031215612d4c57600080fd5b813567ffffffffffffffff811115612d6357600080fd5b820160a0818503121561190f57600080fd5b602081526000825160406020840152612d916060840182612b02565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612dcc8282612b02565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e2357835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612df1565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612e2357835167ffffffffffffffff1683529284019291840191600101612e4b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715612ec457612ec4612e71565b60405290565b60405160c0810167ffffffffffffffff81118282101715612ec457612ec4612e71565b80151581146114be57600080fd5b8035612ae281612eed565b80356fffffffffffffffffffffffffffffffff81168114612ae257600080fd5b600060608284031215612f3857600080fd5b6040516060810181811067ffffffffffffffff82111715612f5b57612f5b612e71565b6040529050808235612f6c81612eed565b8152612f7a60208401612f06565b6020820152612f8b60408401612f06565b60408201525092915050565b600080600060e08486031215612fac57600080fd5b612fb584612aca565b9250612fc48560208601612f26565b9150612fd38560808601612f26565b90509250925092565b60008060208385031215612fef57600080fd5b823567ffffffffffffffff81111561300657600080fd5b61301285828601612bff565b90969095509350505050565b600181811c9082168061303257607f821691505b60208210810361306b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f83011261308257600080fd5b813567ffffffffffffffff8082111561309d5761309d612e71565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156130e3576130e3612e71565b816040528381528660208588010111156130fc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000610100823603121561312f57600080fd5b613137612ea0565b823567ffffffffffffffff8082111561314f57600080fd5b61315b36838701613071565b835261316960208601612aca565b602084015261317a60408601612b9b565b60408401526060850135606084015261319560808601612b9b565b608084015260a08501359150808211156131ae57600080fd5b6131ba36838701613071565b60a084015260c08501359150808211156131d357600080fd5b6131df36838701613071565b60c084015260e08501359150808211156131f857600080fd5b5061320536828601613071565b60e08301525092915050565b601f821115611022576000816000526020600020601f850160051c8101602086101561323a5750805b601f850160051c820191505b8181101561325957828155600101613246565b505050505050565b67ffffffffffffffff83111561327957613279612e71565b61328d83613287835461301e565b83613211565b6000601f8411600181146132df57600085156132a95750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355611b82565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561332e578685013582556020948501946001909201910161330e565b5086821015613369577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b60408152600061338e6040830186612b02565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a082360312156133f157600080fd5b60405160a0810167ffffffffffffffff828210818311171561341557613415612e71565b81604052843591508082111561342a57600080fd5b5061343736828601613071565b82525061344660208401612aca565b6020820152604083013561345981612b79565b604082015260608381013590820152608083013561347681612b79565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec18336030181126134e457600080fd5b9190910192915050565b6000610140823603121561350157600080fd5b613509612eca565b61351283612aca565b815261352060208401612efb565b6020820152604083013567ffffffffffffffff8082111561354057600080fd5b61354c36838701613071565b6040840152606085013591508082111561356557600080fd5b5061357236828601613071565b6060830152506135853660808501612f26565b60808201526135973660e08501612f26565b60a082015292915050565b815167ffffffffffffffff8111156135bc576135bc612e71565b6135d0816135ca845461301e565b84613211565b602080601f83116001811461362357600084156135ed5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613259565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561367057888601518255948401946001909101908401613651565b50858210156136ac57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526136e081840187612b02565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061371e9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612dcc565b60006020828403121561376757600080fd5b815161190f81612eed565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156105f0576105f0613772565b67ffffffffffffffff8416815260e0810161380060208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612386565b606081016105f082848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561388557600080fd5b815161190f81612b79565b80820281158282048414176105f0576105f0613772565b808201808211156105f0576105f0613772565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008261391f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004a6338038062004a63833981016040819052620000359162000869565b8484848484336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f8162000165565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0385811660805282811660c05260ff851660a052600480546001600160a01b031916918316919091179055825115801560e0526200013b576040805160008152602081019091526200013b9084620001df565b506200015a935050506001600160a01b0387169050306000196200033c565b505050505062000ac0565b336001600160a01b038216036200018f57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e05162000200576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200028b57600083828151811062000224576200022462000994565b602090810291909101015190506200023e60028262000422565b1562000281576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000203565b5060005b815181101562000337576000828281518110620002b057620002b062000994565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002dc57506200032e565b620002e960028262000442565b156200032c576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016200028f565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156200038e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003b49190620009aa565b620003c09190620009da565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091529192506200041c918691906200045916565b50505050565b600062000439836001600160a01b0384166200052e565b90505b92915050565b600062000439836001600160a01b03841662000632565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620004a8906001600160a01b03851690849062000684565b805190915015620003375780806020019051810190620004c99190620009f0565b620003375760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b60008181526001830160205260408120548015620006275760006200055560018362000a1b565b85549091506000906200056b9060019062000a1b565b9050808214620005d75760008660000182815481106200058f576200058f62000994565b9060005260206000200154905080876000018481548110620005b557620005b562000994565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620005eb57620005eb62000a31565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200043c565b60009150506200043c565b60008181526001830160205260408120546200067b575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200043c565b5060006200043c565b60606200069584846000856200069d565b949350505050565b606082471015620007005760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000525565b600080866001600160a01b031685876040516200071e919062000a6d565b60006040518083038185875af1925050503d80600081146200075d576040519150601f19603f3d011682016040523d82523d6000602084013e62000762565b606091505b509092509050620007768783838762000781565b979650505050505050565b60608315620007f5578251600003620007ed576001600160a01b0385163b620007ed5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000525565b508162000695565b6200069583838151156200080c5781518083602001fd5b8060405162461bcd60e51b815260040162000525919062000a8b565b6001600160a01b03811681146200083e57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620008648162000828565b919050565b600080600080600060a086880312156200088257600080fd5b85516200088f8162000828565b8095505060208087015160ff81168114620008a957600080fd5b60408801519095506001600160401b0380821115620008c757600080fd5b818901915089601f830112620008dc57600080fd5b815181811115620008f157620008f162000841565b8060051b604051601f19603f8301168101818110858211171562000919576200091962000841565b60405291825284820192508381018501918c8311156200093857600080fd5b938501935b828510156200096157620009518562000857565b845293850193928501926200093d565b809850505050505050620009786060870162000857565b9150620009886080870162000857565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009bd57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156200043c576200043c620009c4565b60006020828403121562000a0357600080fd5b8151801515811462000a1457600080fd5b9392505050565b818103818111156200043c576200043c620009c4565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000a6457818101518382015260200162000a4a565b50506000910152565b6000825162000a8181846020870162000a47565b9190910192915050565b602081526000825180602084015262000aac81604085016020870162000a47565b601f01601f19169190910160400192915050565b60805160a05160c05160e051613f0062000b636000396000818161054801528181611c5401526126a5015260008181610522015281816118980152611f400152600081816102d901528181610ba201528181611a4101528181611afb01528181611b2f01528181611b600152611ba70152600081816102400152818161029501528181610701015281816120c30152818161263b01526128900152613f006000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80639a4575b911610104578063c0d78655116100a2578063dc0bd97111610071578063dc0bd97114610520578063e0351e1314610546578063e8a1da171461056c578063f2fde38b1461057f57600080fd5b8063c0d78655146104d2578063c4bffe2b146104e5578063c75eea9c146104fa578063cf7401f31461050d57600080fd5b8063acfecf91116100de578063acfecf911461041f578063af58d59f14610432578063b0f479a1146104a1578063b7946580146104bf57600080fd5b80639a4575b9146103ca578063a42a7b8b146103ea578063a7cd63b71461040a57600080fd5b806354c8a4f31161017157806379ba50971161014b57806379ba50971461037e5780637d54534e146103865780638926f54f146103995780638da5cb5b146103ac57600080fd5b806354c8a4f31461033857806362ddd3c41461034d5780636d3d1a581461036057600080fd5b8063240028e8116101ad578063240028e81461028557806324f65ee7146102d257806339077537146103035780634c5ef0ed1461032557600080fd5b806301ffc9a7146101d4578063181f5a77146101fc57806321df0da71461023e575b600080fd5b6101e76101e2366004613050565b610592565b60405190151581526020015b60405180910390f35b60408051808201909152601f81527f4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20312e352e310060208201525b6040516101f391906130f6565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b6101e761029336600461312b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016101f3565b610316610311366004613148565b610677565b604051905181526020016101f3565b6101e76103333660046131a1565b610846565b61034b610346366004613270565b610890565b005b61034b61035b3660046131a1565b61090b565b60095473ffffffffffffffffffffffffffffffffffffffff16610260565b61034b6109a8565b61034b61039436600461312b565b610a76565b6101e76103a73660046132dc565b610af7565b60015473ffffffffffffffffffffffffffffffffffffffff16610260565b6103dd6103d83660046132f7565b610b0e565b6040516101f39190613332565b6103fd6103f83660046132dc565b610be7565b6040516101f39190613389565b610412610d52565b6040516101f3919061340b565b61034b61042d3660046131a1565b610d63565b6104456104403660046132dc565b610e7b565b6040516101f3919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff16610260565b6102316104cd3660046132dc565b610f50565b61034b6104e036600461312b565b611000565b6104ed6110db565b6040516101f39190613465565b6104456105083660046132dc565b611193565b61034b61051b3660046135ed565b611265565b7f0000000000000000000000000000000000000000000000000000000000000000610260565b7f00000000000000000000000000000000000000000000000000000000000000006101e7565b61034b61057a366004613270565b6112e9565b61034b61058d36600461312b565b6117fb565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061062557507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061067157507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60408051602081019091526000815261068f8261180f565b60006106e860608401356106e36106a960c0870187613632565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3392505050565b611af7565b905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166340c10f19610736606086016040870161312b565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401600060405180830381600087803b1580156107a357600080fd5b505af11580156107b7573d6000803e3d6000fd5b506107cc92505050606084016040850161312b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08360405161082a91815260200190565b60405180910390a3604080516020810190915290815292915050565b6000610888838360405161085b929190613697565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190611be7565b949350505050565b610898611bff565b61090584848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611c5292505050565b50505050565b610913611bff565b61091c83610af7565b610963576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b6109a38383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611e0892505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109f9576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a7e611bff565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610671600567ffffffffffffffff8416611be7565b6040805180820190915260608082526020820152610b2b82611f02565b610b38826060013561208e565b6040516060830135815233907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a26040518060400160405280610b928460200160208101906104cd91906132dc565b8152602001610bdf6040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610c1090600501612130565b90506000815167ffffffffffffffff811115610c2e57610c2e6134a7565b604051908082528060200260200182016040528015610c6157816020015b6060815260200190600190039081610c4c5790505b50905060005b8251811015610d4a5760086000848381518110610c8657610c866136a7565b602002602001015181526020019081526020016000208054610ca7906136d6565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd3906136d6565b8015610d205780601f10610cf557610100808354040283529160200191610d20565b820191906000526020600020905b815481529060010190602001808311610d0357829003601f168201915b5050505050828281518110610d3757610d376136a7565b6020908102919091010152600101610c67565b509392505050565b6060610d5e6002612130565b905090565b610d6b611bff565b610d7483610af7565b610db6576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161095a565b610df68282604051610dc9929190613697565b604080519182900390912067ffffffffffffffff861660009081526007602052919091206005019061213d565b610e32578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161095a93929190613772565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d768383604051610e6e929190613796565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261067190612149565b67ffffffffffffffff81166000908152600760205260409020600401805460609190610f7b906136d6565b80601f0160208091040260200160405190810160405280929190818152602001828054610fa7906136d6565b8015610ff45780601f10610fc957610100808354040283529160200191610ff4565b820191906000526020600020905b815481529060010190602001808311610fd757829003601f168201915b50505050509050919050565b611008611bff565b73ffffffffffffffffffffffffffffffffffffffff8116611055576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110e96005612130565b90506000815167ffffffffffffffff811115611107576111076134a7565b604051908082528060200260200182016040528015611130578160200160208202803683370190505b50905060005b825181101561118c57828181518110611151576111516136a7565b602002602001015182828151811061116b5761116b6136a7565b67ffffffffffffffff90921660209283029190910190910152600101611136565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261067190612149565b60095473ffffffffffffffffffffffffffffffffffffffff1633148015906112a5575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156112de576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161095a565b6109a38383836121fb565b6112f1611bff565b60005b838110156114de576000858583818110611310576113106136a7565b905060200201602081019061132591906132dc565b905061133c600567ffffffffffffffff831661213d565b61137e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161095a565b67ffffffffffffffff811660009081526007602052604081206113a390600501612130565b905060005b815181101561140f576114068282815181106113c6576113c66136a7565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161213d90919063ffffffff16565b506001016113a8565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906114786004830182612fe3565b600582016000818161148a828261301d565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d859916945060200192506114cc915050565b60405180910390a150506001016112f4565b5060005b818110156117f45760008383838181106114fe576114fe6136a7565b905060200281019061151091906137aa565b61151990613876565b905061152a816060015160006122e5565b611539816080015160006122e5565b806040015151600003611578576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516115909060059067ffffffffffffffff16612422565b6115d55780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161095a565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a90910299909316171790941695909517909255909202909117600382015590820151600482019061175890826139ed565b5060005b82602001515181101561179c57611794836000015184602001518381518110611787576117876136a7565b6020026020010151611e08565b60010161175c565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c282600001518360400151846060015185608001516040516117e29493929190613b07565b60405180910390a150506001016114e2565b5050505050565b611803611bff565b61180c8161242e565b50565b61182261029360a083016080840161312b565b6118815761183660a082016080830161312b565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161095a565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6118cd60408401602085016132dc565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa15801561193e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119629190613ba0565b15611999576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6119b16119ac60408301602084016132dc565b6124f2565b6119d16119c460408301602084016132dc565b61033360a0840184613632565b611a16576119e260a0820182613632565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161095a929190613796565b61180c611a2960408301602084016132dc565b8260600135612618565b60008151600003611a6557507f0000000000000000000000000000000000000000000000000000000000000000919050565b8151602014611aa257816040517f953576f700000000000000000000000000000000000000000000000000000000815260040161095a91906130f6565b600082806020019051810190611ab89190613bbd565b905060ff81111561067157826040517f953576f700000000000000000000000000000000000000000000000000000000815260040161095a91906130f6565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff1603611b2d575081610671565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff161115611ba157611b857f000000000000000000000000000000000000000000000000000000000000000083613c05565b611b9090600a613d3e565b611b9a9084613d4d565b9050610671565b611bcb827f0000000000000000000000000000000000000000000000000000000000000000613c05565b611bd690600a613d3e565b611be09084613d88565b9392505050565b60008181526001830160205260408120541515611be0565b60015473ffffffffffffffffffffffffffffffffffffffff163314611c50576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611ca9576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611d3f576000838281518110611cc957611cc96136a7565b60200260200101519050611ce781600261265f90919063ffffffff16565b15611d365760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611cac565b5060005b81518110156109a3576000828281518110611d6057611d606136a7565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611da45750611e00565b611daf600282612681565b15611dfe5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611d43565b8051600003611e43576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff8416600090815260079092526040909120611e759060050182612422565b611eaf5782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161095a929190613d9f565b6000818152600860205260409020611ec783826139ed565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea83604051610e6e91906130f6565b611f1561029360a083016080840161312b565b611f295761183660a082016080830161312b565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611f7560408401602085016132dc565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611fe6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200a9190613ba0565b15612041576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612059612054606083016040840161312b565b6126a3565b61207161206c60408301602084016132dc565b612722565b61180c61208460408301602084016132dc565b8260600135612870565b6040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639dc29fac90604401600060405180830381600087803b15801561211c57600080fd5b505af11580156117f4573d6000803e3d6000fd5b60606000611be0836128b4565b6000611be0838361290f565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526121d782606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426121bb9190613dc2565b85608001516fffffffffffffffffffffffffffffffff16612a02565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61220483610af7565b612246576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161095a565b6122518260006122e5565b67ffffffffffffffff831660009081526007602052604090206122749083612a2a565b61227f8160006122e5565b67ffffffffffffffff831660009081526007602052604090206122a59060020182612a2a565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516122d893929190613dd5565b60405180910390a1505050565b8151156123b05781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff1610158061233b575060408201516fffffffffffffffffffffffffffffffff16155b1561237457816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161095a9190613e58565b80156123ac576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff161515806123e9575060208201516fffffffffffffffffffffffffffffffff1615155b156123ac57816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161095a9190613e58565b6000611be08383612bcc565b3373ffffffffffffffffffffffffffffffffffffffff82160361247d576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6124fb81610af7565b61253d576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161095a565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa1580156125bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125e09190613ba0565b61180c576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161095a565b67ffffffffffffffff821660009081526007602052604090206123ac90600201827f0000000000000000000000000000000000000000000000000000000000000000612c1b565b6000611be08373ffffffffffffffffffffffffffffffffffffffff841661290f565b6000611be08373ffffffffffffffffffffffffffffffffffffffff8416612bcc565b7f00000000000000000000000000000000000000000000000000000000000000001561180c576126d4600282612f9e565b61180c576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161095a565b61272b81610af7565b61276d576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161095a565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa1580156127e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280a9190613e94565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461180c576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161095a565b67ffffffffffffffff821660009081526007602052604090206123ac90827f0000000000000000000000000000000000000000000000000000000000000000612c1b565b606081600001805480602002602001604051908101604052809291908181526020018280548015610ff457602002820191906000526020600020905b8154815260200190600101908083116128f05750505050509050919050565b600081815260018301602052604081205480156129f8576000612933600183613dc2565b855490915060009061294790600190613dc2565b90508082146129ac576000866000018281548110612967576129676136a7565b906000526020600020015490508087600001848154811061298a5761298a6136a7565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806129bd576129bd613eb1565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610671565b6000915050610671565b6000612a2185612a128486613d88565b612a1c9087613ee0565b612fcd565b95945050505050565b8154600090612a5390700100000000000000000000000000000000900463ffffffff1642613dc2565b90508015612af55760018301548354612a9b916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612a02565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612b1b916fffffffffffffffffffffffffffffffff9081169116612fcd565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906122d8908490613e58565b6000818152600183016020526040812054612c1357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610671565b506000610671565b825474010000000000000000000000000000000000000000900460ff161580612c42575081155b15612c4c57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612c9290700100000000000000000000000000000000900463ffffffff1642613dc2565b90508015612d525781831115612cd4576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612d0e9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612a02565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612e095773ffffffffffffffffffffffffffffffffffffffff8416612db1576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161095a565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161095a565b84831015612f1c5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612e4d9082613dc2565b612e57878a613dc2565b612e619190613ee0565b612e6b9190613d4d565b905073ffffffffffffffffffffffffffffffffffffffff8616612ec4576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161095a565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161095a565b612f268584613dc2565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611be0565b6000818310612fdc5781611be0565b5090919050565b508054612fef906136d6565b6000825580601f10612fff575050565b601f01602090049060005260206000209081019061180c9190613037565b508054600082559060005260206000209081019061180c91905b5b8082111561304c5760008155600101613038565b5090565b60006020828403121561306257600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611be057600080fd5b6000815180845260005b818110156130b85760208185018101518683018201520161309c565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000611be06020830184613092565b73ffffffffffffffffffffffffffffffffffffffff8116811461180c57600080fd5b60006020828403121561313d57600080fd5b8135611be081613109565b60006020828403121561315a57600080fd5b813567ffffffffffffffff81111561317157600080fd5b82016101008185031215611be057600080fd5b803567ffffffffffffffff8116811461319c57600080fd5b919050565b6000806000604084860312156131b657600080fd5b6131bf84613184565b9250602084013567ffffffffffffffff808211156131dc57600080fd5b818601915086601f8301126131f057600080fd5b8135818111156131ff57600080fd5b87602082850101111561321157600080fd5b6020830194508093505050509250925092565b60008083601f84011261323657600080fd5b50813567ffffffffffffffff81111561324e57600080fd5b6020830191508360208260051b850101111561326957600080fd5b9250929050565b6000806000806040858703121561328657600080fd5b843567ffffffffffffffff8082111561329e57600080fd5b6132aa88838901613224565b909650945060208701359150808211156132c357600080fd5b506132d087828801613224565b95989497509550505050565b6000602082840312156132ee57600080fd5b611be082613184565b60006020828403121561330957600080fd5b813567ffffffffffffffff81111561332057600080fd5b820160a08185031215611be057600080fd5b60208152600082516040602084015261334e6060840182613092565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612a218282613092565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b828110156133fe577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526133ec858351613092565b945092850192908501906001016133b2565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561345957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613427565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561345957835167ffffffffffffffff1683529284019291840191600101613481565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156134f9576134f96134a7565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613546576135466134a7565b604052919050565b801515811461180c57600080fd5b80356fffffffffffffffffffffffffffffffff8116811461319c57600080fd5b60006060828403121561358e57600080fd5b6040516060810181811067ffffffffffffffff821117156135b1576135b16134a7565b60405290508082356135c28161354e565b81526135d06020840161355c565b60208201526135e16040840161355c565b60408201525092915050565b600080600060e0848603121561360257600080fd5b61360b84613184565b925061361a856020860161357c565b9150613629856080860161357c565b90509250925092565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261366757600080fd5b83018035915067ffffffffffffffff82111561368257600080fd5b60200191503681900382131561326957600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c908216806136ea57607f821691505b602082108103613723577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000612a21604083018486613729565b602081526000610888602083018486613729565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181126137de57600080fd5b9190910192915050565b600082601f8301126137f957600080fd5b813567ffffffffffffffff811115613813576138136134a7565b61384460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016134ff565b81815284602083860101111561385957600080fd5b816020850160208301376000918101602001919091529392505050565b6000610120823603121561388957600080fd5b6138916134d6565b61389a83613184565b815260208084013567ffffffffffffffff808211156138b857600080fd5b9085019036601f8301126138cb57600080fd5b8135818111156138dd576138dd6134a7565b8060051b6138ec8582016134ff565b918252838101850191858101903684111561390657600080fd5b86860192505b83831015613942578235858111156139245760008081fd5b6139323689838a01016137e8565b835250918601919086019061390c565b808789015250505050604086013592508083111561395f57600080fd5b505061396d368286016137e8565b604083015250613980366060850161357c565b60608201526139923660c0850161357c565b608082015292915050565b601f8211156109a3576000816000526020600020601f850160051c810160208610156139c65750805b601f850160051c820191505b818110156139e5578281556001016139d2565b505050505050565b815167ffffffffffffffff811115613a0757613a076134a7565b613a1b81613a1584546136d6565b8461399d565b602080601f831160018114613a6e5760008415613a385750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556139e5565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613abb57888601518255948401946001909101908401613a9c565b5085821015613af757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613b2b81840187613092565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613b699050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612a21565b600060208284031215613bb257600080fd5b8151611be08161354e565b600060208284031215613bcf57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561067157610671613bd6565b600181815b80851115613c7757817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613c5d57613c5d613bd6565b80851615613c6a57918102915b93841c9390800290613c23565b509250929050565b600082613c8e57506001610671565b81613c9b57506000610671565b8160018114613cb15760028114613cbb57613cd7565b6001915050610671565b60ff841115613ccc57613ccc613bd6565b50506001821b610671565b5060208310610133831016604e8410600b8410161715613cfa575081810a610671565b613d048383613c1e565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613d3657613d36613bd6565b029392505050565b6000611be060ff841683613c7f565b600082613d83577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761067157610671613bd6565b67ffffffffffffffff831681526040602082015260006108886040830184613092565b8181038181111561067157610671613bd6565b67ffffffffffffffff8416815260e08101613e2160208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610888565b6060810161067182848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215613ea657600080fd5b8151611be081613109565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8082018082111561067157610671613bd656fea164736f6c6343000818000a", } var BurnWithFromMintTokenPoolABI = BurnWithFromMintTokenPoolMetaData.ABI var BurnWithFromMintTokenPoolBin = BurnWithFromMintTokenPoolMetaData.Bin -func DeployBurnWithFromMintTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, rmnProxy common.Address, router common.Address) (common.Address, *types.Transaction, *BurnWithFromMintTokenPool, error) { +func DeployBurnWithFromMintTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, localTokenDecimals uint8, allowlist []common.Address, rmnProxy common.Address, router common.Address) (common.Address, *types.Transaction, *BurnWithFromMintTokenPool, error) { parsed, err := BurnWithFromMintTokenPoolMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -99,7 +98,7 @@ func DeployBurnWithFromMintTokenPool(auth *bind.TransactOpts, backend bind.Contr return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnWithFromMintTokenPoolBin), backend, token, allowlist, rmnProxy, router) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BurnWithFromMintTokenPoolBin), backend, token, localTokenDecimals, allowlist, rmnProxy, router) if err != nil { return common.Address{}, nil, nil, err } @@ -332,26 +331,26 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetRat return _BurnWithFromMintTokenPool.Contract.GetRateLimitAdmin(&_BurnWithFromMintTokenPool.CallOpts) } -func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetRemotePools(opts *bind.CallOpts, remoteChainSelector uint64) ([][]byte, error) { var out []interface{} - err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getRemotePools", remoteChainSelector) if err != nil { - return *new([]byte), err + return *new([][]byte), err } - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + out0 := *abi.ConvertType(out[0], new([][]byte)).(*[][]byte) return out0, err } -func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { - return _BurnWithFromMintTokenPool.Contract.GetRemotePool(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetRemotePools(remoteChainSelector uint64) ([][]byte, error) { + return _BurnWithFromMintTokenPool.Contract.GetRemotePools(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) } -func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { - return _BurnWithFromMintTokenPool.Contract.GetRemotePool(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetRemotePools(remoteChainSelector uint64) ([][]byte, error) { + return _BurnWithFromMintTokenPool.Contract.GetRemotePools(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector) } func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { @@ -464,6 +463,50 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetTok return _BurnWithFromMintTokenPool.Contract.GetToken(&_BurnWithFromMintTokenPool.CallOpts) } +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) GetTokenDecimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "getTokenDecimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) GetTokenDecimals() (uint8, error) { + return _BurnWithFromMintTokenPool.Contract.GetTokenDecimals(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) GetTokenDecimals() (uint8, error) { + return _BurnWithFromMintTokenPool.Contract.GetTokenDecimals(&_BurnWithFromMintTokenPool.CallOpts) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) IsRemotePool(opts *bind.CallOpts, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + var out []interface{} + err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "isRemotePool", remoteChainSelector, remotePoolAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) IsRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + return _BurnWithFromMintTokenPool.Contract.IsRemotePool(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCallerSession) IsRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + return _BurnWithFromMintTokenPool.Contract.IsRemotePool(&_BurnWithFromMintTokenPool.CallOpts, remoteChainSelector, remotePoolAddress) +} + func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { var out []interface{} err := _BurnWithFromMintTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) @@ -586,6 +629,18 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) Ac return _BurnWithFromMintTokenPool.Contract.AcceptOwnership(&_BurnWithFromMintTokenPool.TransactOpts) } +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) AddRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "addRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) AddRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.AddRemotePool(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) AddRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.AddRemotePool(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { return _BurnWithFromMintTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) } @@ -598,16 +653,16 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) Ap return _BurnWithFromMintTokenPool.Contract.ApplyAllowListUpdates(&_BurnWithFromMintTokenPool.TransactOpts, removes, adds) } -func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _BurnWithFromMintTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "applyChainUpdates", remoteChainSelectorsToRemove, chainsToAdd) } -func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _BurnWithFromMintTokenPool.Contract.ApplyChainUpdates(&_BurnWithFromMintTokenPool.TransactOpts, chains) +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) ApplyChainUpdates(remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.ApplyChainUpdates(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelectorsToRemove, chainsToAdd) } -func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _BurnWithFromMintTokenPool.Contract.ApplyChainUpdates(&_BurnWithFromMintTokenPool.TransactOpts, chains) +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) ApplyChainUpdates(remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.ApplyChainUpdates(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelectorsToRemove, chainsToAdd) } func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { @@ -634,6 +689,18 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) Re return _BurnWithFromMintTokenPool.Contract.ReleaseOrMint(&_BurnWithFromMintTokenPool.TransactOpts, releaseOrMintIn) } +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) RemoveRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.contract.Transact(opts, "removeRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) RemoveRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.RemoveRemotePool(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) RemoveRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _BurnWithFromMintTokenPool.Contract.RemoveRemotePool(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { return _BurnWithFromMintTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) } @@ -658,18 +725,6 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) Se return _BurnWithFromMintTokenPool.Contract.SetRateLimitAdmin(&_BurnWithFromMintTokenPool.TransactOpts, rateLimitAdmin) } -func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _BurnWithFromMintTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) -} - -func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _BurnWithFromMintTokenPool.Contract.SetRemotePool(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) -} - -func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _BurnWithFromMintTokenPool.Contract.SetRemotePool(&_BurnWithFromMintTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) -} - func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { return _BurnWithFromMintTokenPool.contract.Transact(opts, "setRouter", newRouter) } @@ -2320,8 +2375,136 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseReleas return event, nil } -type BurnWithFromMintTokenPoolRemotePoolSetIterator struct { - Event *BurnWithFromMintTokenPoolRemotePoolSet +type BurnWithFromMintTokenPoolRemotePoolAddedIterator struct { + Event *BurnWithFromMintTokenPoolRemotePoolAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *BurnWithFromMintTokenPoolRemotePoolAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolRemotePoolAdded) + 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 + } + } + + select { + case log := <-it.logs: + it.Event = new(BurnWithFromMintTokenPoolRemotePoolAdded) + 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() + } +} + +func (it *BurnWithFromMintTokenPoolRemotePoolAddedIterator) Error() error { + return it.fail +} + +func (it *BurnWithFromMintTokenPoolRemotePoolAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type BurnWithFromMintTokenPoolRemotePoolAdded struct { + RemoteChainSelector uint64 + RemotePoolAddress []byte + Raw types.Log +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterRemotePoolAdded(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnWithFromMintTokenPoolRemotePoolAddedIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "RemotePoolAdded", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &BurnWithFromMintTokenPoolRemotePoolAddedIterator{contract: _BurnWithFromMintTokenPool.contract, event: "RemotePoolAdded", logs: logs, sub: sub}, nil +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchRemotePoolAdded(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolRemotePoolAdded, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "RemotePoolAdded", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(BurnWithFromMintTokenPoolRemotePoolAdded) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "RemotePoolAdded", 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 +} + +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseRemotePoolAdded(log types.Log) (*BurnWithFromMintTokenPoolRemotePoolAdded, error) { + event := new(BurnWithFromMintTokenPoolRemotePoolAdded) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "RemotePoolAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type BurnWithFromMintTokenPoolRemotePoolRemovedIterator struct { + Event *BurnWithFromMintTokenPoolRemotePoolRemoved contract *bind.BoundContract event string @@ -2332,7 +2515,7 @@ type BurnWithFromMintTokenPoolRemotePoolSetIterator struct { fail error } -func (it *BurnWithFromMintTokenPoolRemotePoolSetIterator) Next() bool { +func (it *BurnWithFromMintTokenPoolRemotePoolRemovedIterator) Next() bool { if it.fail != nil { return false @@ -2341,7 +2524,7 @@ func (it *BurnWithFromMintTokenPoolRemotePoolSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(BurnWithFromMintTokenPoolRemotePoolSet) + it.Event = new(BurnWithFromMintTokenPoolRemotePoolRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2356,7 +2539,7 @@ func (it *BurnWithFromMintTokenPoolRemotePoolSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(BurnWithFromMintTokenPoolRemotePoolSet) + it.Event = new(BurnWithFromMintTokenPoolRemotePoolRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2371,44 +2554,43 @@ func (it *BurnWithFromMintTokenPoolRemotePoolSetIterator) Next() bool { } } -func (it *BurnWithFromMintTokenPoolRemotePoolSetIterator) Error() error { +func (it *BurnWithFromMintTokenPoolRemotePoolRemovedIterator) Error() error { return it.fail } -func (it *BurnWithFromMintTokenPoolRemotePoolSetIterator) Close() error { +func (it *BurnWithFromMintTokenPoolRemotePoolRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -type BurnWithFromMintTokenPoolRemotePoolSet struct { +type BurnWithFromMintTokenPoolRemotePoolRemoved struct { RemoteChainSelector uint64 - PreviousPoolAddress []byte RemotePoolAddress []byte Raw types.Log } -func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnWithFromMintTokenPoolRemotePoolSetIterator, error) { +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) FilterRemotePoolRemoved(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnWithFromMintTokenPoolRemotePoolRemovedIterator, error) { var remoteChainSelectorRule []interface{} for _, remoteChainSelectorItem := range remoteChainSelector { remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + logs, sub, err := _BurnWithFromMintTokenPool.contract.FilterLogs(opts, "RemotePoolRemoved", remoteChainSelectorRule) if err != nil { return nil, err } - return &BurnWithFromMintTokenPoolRemotePoolSetIterator{contract: _BurnWithFromMintTokenPool.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil + return &BurnWithFromMintTokenPoolRemotePoolRemovedIterator{contract: _BurnWithFromMintTokenPool.contract, event: "RemotePoolRemoved", logs: logs, sub: sub}, nil } -func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchRemotePoolRemoved(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolRemotePoolRemoved, remoteChainSelector []uint64) (event.Subscription, error) { var remoteChainSelectorRule []interface{} for _, remoteChainSelectorItem := range remoteChainSelector { remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + logs, sub, err := _BurnWithFromMintTokenPool.contract.WatchLogs(opts, "RemotePoolRemoved", remoteChainSelectorRule) if err != nil { return nil, err } @@ -2418,8 +2600,8 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchRemote select { case log := <-logs: - event := new(BurnWithFromMintTokenPoolRemotePoolSet) - if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + event := new(BurnWithFromMintTokenPoolRemotePoolRemoved) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "RemotePoolRemoved", log); err != nil { return err } event.Raw = log @@ -2440,9 +2622,9 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) WatchRemote }), nil } -func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseRemotePoolSet(log types.Log) (*BurnWithFromMintTokenPoolRemotePoolSet, error) { - event := new(BurnWithFromMintTokenPoolRemotePoolSet) - if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { +func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPoolFilterer) ParseRemotePoolRemoved(log types.Log) (*BurnWithFromMintTokenPoolRemotePoolRemoved, error) { + event := new(BurnWithFromMintTokenPoolRemotePoolRemoved) + if err := _BurnWithFromMintTokenPool.contract.UnpackLog(event, "RemotePoolRemoved", log); err != nil { return nil, err } event.Raw = log @@ -2712,8 +2894,10 @@ func (_BurnWithFromMintTokenPool *BurnWithFromMintTokenPool) ParseLog(log types. return _BurnWithFromMintTokenPool.ParseRateLimitAdminSet(log) case _BurnWithFromMintTokenPool.abi.Events["Released"].ID: return _BurnWithFromMintTokenPool.ParseReleased(log) - case _BurnWithFromMintTokenPool.abi.Events["RemotePoolSet"].ID: - return _BurnWithFromMintTokenPool.ParseRemotePoolSet(log) + case _BurnWithFromMintTokenPool.abi.Events["RemotePoolAdded"].ID: + return _BurnWithFromMintTokenPool.ParseRemotePoolAdded(log) + case _BurnWithFromMintTokenPool.abi.Events["RemotePoolRemoved"].ID: + return _BurnWithFromMintTokenPool.ParseRemotePoolRemoved(log) case _BurnWithFromMintTokenPool.abi.Events["RouterUpdated"].ID: return _BurnWithFromMintTokenPool.ParseRouterUpdated(log) case _BurnWithFromMintTokenPool.abi.Events["TokensConsumed"].ID: @@ -2776,8 +2960,12 @@ func (BurnWithFromMintTokenPoolReleased) Topic() common.Hash { return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") } -func (BurnWithFromMintTokenPoolRemotePoolSet) Topic() common.Hash { - return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +func (BurnWithFromMintTokenPoolRemotePoolAdded) Topic() common.Hash { + return common.HexToHash("0x7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea") +} + +func (BurnWithFromMintTokenPoolRemotePoolRemoved) Topic() common.Hash { + return common.HexToHash("0x52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d76") } func (BurnWithFromMintTokenPoolRouterUpdated) Topic() common.Hash { @@ -2803,7 +2991,7 @@ type BurnWithFromMintTokenPoolInterface interface { GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) - GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + GetRemotePools(opts *bind.CallOpts, remoteChainSelector uint64) ([][]byte, error) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) @@ -2815,6 +3003,10 @@ type BurnWithFromMintTokenPoolInterface interface { GetToken(opts *bind.CallOpts) (common.Address, error) + GetTokenDecimals(opts *bind.CallOpts) (uint8, error) + + IsRemotePool(opts *bind.CallOpts, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) @@ -2827,20 +3019,22 @@ type BurnWithFromMintTokenPoolInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + AddRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) - ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + ApplyChainUpdates(opts *bind.TransactOpts, remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + RemoveRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) - SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) - SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) @@ -2923,11 +3117,17 @@ type BurnWithFromMintTokenPoolInterface interface { ParseReleased(log types.Log) (*BurnWithFromMintTokenPoolReleased, error) - FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnWithFromMintTokenPoolRemotePoolSetIterator, error) + FilterRemotePoolAdded(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnWithFromMintTokenPoolRemotePoolAddedIterator, error) + + WatchRemotePoolAdded(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolRemotePoolAdded, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolAdded(log types.Log) (*BurnWithFromMintTokenPoolRemotePoolAdded, error) + + FilterRemotePoolRemoved(opts *bind.FilterOpts, remoteChainSelector []uint64) (*BurnWithFromMintTokenPoolRemotePoolRemovedIterator, error) - WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + WatchRemotePoolRemoved(opts *bind.WatchOpts, sink chan<- *BurnWithFromMintTokenPoolRemotePoolRemoved, remoteChainSelector []uint64) (event.Subscription, error) - ParseRemotePoolSet(log types.Log) (*BurnWithFromMintTokenPoolRemotePoolSet, error) + ParseRemotePoolRemoved(log types.Log) (*BurnWithFromMintTokenPoolRemotePoolRemoved, error) FilterRouterUpdated(opts *bind.FilterOpts) (*BurnWithFromMintTokenPoolRouterUpdatedIterator, error) diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go index 307decf3b2c..044c75b8b40 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go @@ -74,23 +74,22 @@ type RateLimiterTokenBucket struct { type TokenPoolChainUpdate struct { RemoteChainSelector uint64 - Allowed bool - RemotePoolAddress []byte + RemotePoolAddresses [][]byte RemoteTokenAddress []byte OutboundRateLimiterConfig RateLimiterConfig InboundRateLimiterConfig RateLimiterConfig } var LockReleaseTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b50604051620048e9380380620048e98339810160408190526200003591620004fe565b84848483336000816200005b57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008e576200008e8162000148565b50506001600160a01b0384161580620000ae57506001600160a01b038116155b80620000c157506001600160a01b038216155b15620000e0576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c0526200013357604080516000815260208101909152620001339084620001c2565b5050505090151560e052506200066f92505050565b336001600160a01b038216036200017257604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620001e3576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200026e57600083828151811062000207576200020762000621565b60209081029190910101519050620002216002826200031f565b1562000264576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620001e6565b5060005b81518110156200031a57600082828151811062000293576200029362000621565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002bf575062000311565b620002cc6002826200033f565b156200030f576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000272565b505050565b600062000336836001600160a01b03841662000356565b90505b92915050565b600062000336836001600160a01b0384166200045a565b600081815260018301602052604081205480156200044f5760006200037d60018362000637565b8554909150600090620003939060019062000637565b9050808214620003ff576000866000018281548110620003b757620003b762000621565b9060005260206000200154905080876000018481548110620003dd57620003dd62000621565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000413576200041362000659565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000339565b600091505062000339565b6000818152600183016020526040812054620004a35750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000339565b50600062000339565b6001600160a01b0381168114620004c257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620004e881620004ac565b919050565b80518015158114620004e857600080fd5b600080600080600060a086880312156200051757600080fd5b85516200052481620004ac565b602087810151919650906001600160401b03808211156200054457600080fd5b818901915089601f8301126200055957600080fd5b8151818111156200056e576200056e620004c5565b8060051b604051601f19603f83011681018181108582111715620005965762000596620004c5565b60405291825284820192508381018501918c831115620005b557600080fd5b938501935b82851015620005de57620005ce85620004db565b84529385019392850192620005ba565b809950505050505050620005f560408701620004db565b92506200060560608701620004ed565b91506200061560808701620004db565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b818103818111156200033957634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516141de6200070b600039600081816104ef015261174501526000818161059c01528181611cb1015261272501526000818161057601528181611b120152611f67015260008181610290015281816102e50152818161077a0152818161084c015281816108ed0152818161180701528181611a3201528181611e87015281816126bb015261291001526141de6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80638da5cb5b1161010f578063c4bffe2b116100a2578063dc0bd97111610071578063dc0bd97114610574578063e0351e131461059a578063eb521a4c146105c0578063f2fde38b146105d357600080fd5b8063c4bffe2b14610526578063c75eea9c1461053b578063cf7401f31461054e578063db6327dc1461056157600080fd5b8063b0f479a1116100de578063b0f479a1146104bc578063b7946580146104da578063bb98546b146104ed578063c0d786551461051357600080fd5b80638da5cb5b146103fa5780639a4575b914610418578063a7cd63b714610438578063af58d59f1461044d57600080fd5b806354c8a4f31161018757806378a010b21161015657806378a010b2146103b957806379ba5097146103cc5780637d54534e146103d45780638926f54f146103e757600080fd5b806354c8a4f31461036257806366320087146103755780636cfd1553146103885780636d3d1a581461039b57600080fd5b806321df0da7116101c357806321df0da71461028e578063240028e8146102d55780633907753714610322578063432a6ba31461034457600080fd5b806301ffc9a7146101f55780630a2fd4931461021d5780630a861f2a1461023d578063181f5a7714610252575b600080fd5b6102086102033660046132ba565b6105e6565b60405190151581526020015b60405180910390f35b61023061022b366004613319565b610642565b60405161021491906133a2565b61025061024b3660046133b5565b6106f2565b005b6102306040518060400160405280601a81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e3000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b6102086102e33660046133fb565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b610335610330366004613418565b6108a3565b60405190518152602001610214565b60095473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103703660046134a0565b6109a9565b61025061038336600461350c565b610a24565b6102506103963660046133fb565b610b00565b60085473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102506103c7366004613538565b610b4f565b610250610cbe565b6102506103e23660046133fb565b610d8c565b6102086103f5366004613319565b610e0d565b60015473ffffffffffffffffffffffffffffffffffffffff166102b0565b61042b6104263660046135bb565b610e24565b60405161021491906135f6565b610440610ebe565b6040516102149190613656565b61046061045b366004613319565b610ecf565b604051610214919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102b0565b6102306104e8366004613319565b610fa4565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105213660046133fb565b610fcf565b61052e6110aa565b60405161021491906136b0565b610460610549366004613319565b611162565b61025061055c366004613818565b611234565b61025061056f36600461385d565b6112bd565b7f00000000000000000000000000000000000000000000000000000000000000006102b0565b7f0000000000000000000000000000000000000000000000000000000000000000610208565b6102506105ce3660046133b5565b611743565b6102506105e13660046133fb565b61185f565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d4056600000000000000000000000000000000000000000000000000000000148061063c575061063c82611873565b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061066d9061389f565b80601f01602080910402602001604051908101604052809291908181526020018280546106999061389f565b80156106e65780601f106106bb576101008083540402835291602001916106e6565b820191906000526020600020905b8154815290600101906020018083116106c957829003601f168201915b50505050509050919050565b60095473ffffffffffffffffffffffffffffffffffffffff16331461074a576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa91906138f2565b1015610832576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611957565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c36108be836139b6565b611a2b565b6109186108d660608401604085016133fb565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906060850135611957565b61092860608301604084016133fb565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52846060013560405161098a91815260200190565b60405180910390a3506040805160208101909152606090910135815290565b6109b1611c5c565b610a1e84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611caf92505050565b50505050565b610a2c611c5c565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610a9457600080fd5b505af1158015610aa8573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610af491815260200190565b60405180910390a25050565b610b08611c5c565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b57611c5c565b610b6083610e0d565b610ba2576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b67ffffffffffffffff831660009081526007602052604081206004018054610bc99061389f565b80601f0160208091040260200160405190810160405280929190818152602001828054610bf59061389f565b8015610c425780601f10610c1757610100808354040283529160200191610c42565b820191906000526020600020905b815481529060010190602001808311610c2557829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610c71838583613afb565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610cb093929190613c16565b60405180910390a250505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d0f576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610d94611c5c565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b600061063c600567ffffffffffffffff8416611e65565b6040805180820190915260608082526020820152610e49610e4483613c7a565b611e80565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610ea38460200160208101906104e89190613319565b81526040805160208181019092526000815291015292915050565b6060610eca600261204a565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600390910154808416606083015291909104909116608082015261063c90612057565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061066d9061389f565b610fd7611c5c565b73ffffffffffffffffffffffffffffffffffffffff8116611024576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006110b8600561204a565b90506000815167ffffffffffffffff8111156110d6576110d66136f2565b6040519080825280602002602001820160405280156110ff578160200160208202803683370190505b50905060005b825181101561115b5782818151811061112057611120613d1c565b602002602001015182828151811061113a5761113a613d1c565b67ffffffffffffffff90921660209283029190910190910152600101611105565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261063c90612057565b60085473ffffffffffffffffffffffffffffffffffffffff163314801590611274575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156112ad576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b6112b8838383612109565b505050565b6112c5611c5c565b60005b818110156112b85760008383838181106112e4576112e4613d1c565b90506020028101906112f69190613d4b565b6112ff90613d89565b905061131481608001518260200151156121f3565b6113278160a001518260200151156121f3565b8060200151156116235780516113499060059067ffffffffffffffff1661232c565b61138e5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b60408101515115806113a35750606081015151155b156113da576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906115bb9082613e3d565b50606082015160058201906115d09082613e3d565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506116169493929190613f57565b60405180910390a161173a565b805161163b9060059067ffffffffffffffff16612338565b6116805780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610741565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff000000000000000000000000000000000000000000908116825560018201839055600282018054909116905560038101829055906116e9600483018261326c565b6116f760058301600061326c565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b506001016112c8565b7f000000000000000000000000000000000000000000000000000000000000000061179a576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095473ffffffffffffffffffffffffffffffffffffffff1633146117ed576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b61182f73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612344565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611867611c5c565b611870816123a2565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061190657507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061063c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112b89084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612466565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611ac05760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611b6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b929190613ff0565b15611bc9576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bd68160200151612572565b6000611be58260200151610642565b9050805160001480611c09575080805190602001208260a001518051906020012014155b15611c46578160a001516040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161074191906133a2565b611c5882602001518360600151612698565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611cad576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000611d06576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015611d9c576000838281518110611d2657611d26613d1c565b60200260200101519050611d448160026126df90919063ffffffff16565b15611d935760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611d09565b5060005b81518110156112b8576000828281518110611dbd57611dbd613d1c565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e015750611e5d565b611e0c600282612701565b15611e5b5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101611da0565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611f155760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610741565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe79190613ff0565b1561201e576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61202b8160400151612723565b61203881602001516127a2565b611870816020015182606001516128f0565b60606000611e7983612934565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526120e582606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426120c9919061403c565b85608001516fffffffffffffffffffffffffffffffff1661298f565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61211283610e0d565b612154576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610741565b61215f8260006121f3565b67ffffffffffffffff8316600090815260076020526040902061218290836129b9565b61218d8160006121f3565b67ffffffffffffffff831660009081526007602052604090206121b390600201826129b9565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516121e69392919061404f565b60405180910390a1505050565b8151156122ba5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612249575060408201516fffffffffffffffffffffffffffffffff16155b1561228257816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161074191906140d2565b8015611c58576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff161515806122f3575060208201516fffffffffffffffffffffffffffffffff1615155b15611c5857816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161074191906140d2565b6000611e798383612b5b565b6000611e798383612baa565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610a1e9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016119a9565b3373ffffffffffffffffffffffffffffffffffffffff8216036123f1576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006124c8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612c9d9092919063ffffffff16565b8051909150156112b857808060200190518101906124e69190613ff0565b6112b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610741565b61257b81610e0d565b6125bd576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa15801561263c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126609190613ff0565b611870576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c5890600201827f0000000000000000000000000000000000000000000000000000000000000000612cac565b6000611e798373ffffffffffffffffffffffffffffffffffffffff8416612baa565b6000611e798373ffffffffffffffffffffffffffffffffffffffff8416612b5b565b7f0000000000000000000000000000000000000000000000000000000000000000156118705761275460028261302f565b611870576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610741565b6127ab81610e0d565b6127ed576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610741565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612866573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061288a919061410e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611870576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610741565b67ffffffffffffffff82166000908152600760205260409020611c5890827f0000000000000000000000000000000000000000000000000000000000000000612cac565b6060816000018054806020026020016040519081016040528092919081815260200182805480156106e657602002820191906000526020600020905b8154815260200190600101908083116129705750505050509050919050565b60006129ae8561299f848661412b565b6129a99087614142565b61305e565b90505b949350505050565b81546000906129e290700100000000000000000000000000000000900463ffffffff164261403c565b90508015612a845760018301548354612a2a916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661298f565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612aaa916fffffffffffffffffffffffffffffffff908116911661305e565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906121e69084906140d2565b6000818152600183016020526040812054612ba25750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561063c565b50600061063c565b60008181526001830160205260408120548015612c93576000612bce60018361403c565b8554909150600090612be29060019061403c565b9050808214612c47576000866000018281548110612c0257612c02613d1c565b9060005260206000200154905080876000018481548110612c2557612c25613d1c565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612c5857612c58614155565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061063c565b600091505061063c565b60606129b18484600085613074565b825474010000000000000000000000000000000000000000900460ff161580612cd3575081155b15612cdd57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612d2390700100000000000000000000000000000000900463ffffffff164261403c565b90508015612de35781831115612d65576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612d9f9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661298f565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612e9a5773ffffffffffffffffffffffffffffffffffffffff8416612e42576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610741565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610741565b84831015612fad5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612ede908261403c565b612ee8878a61403c565b612ef29190614142565b612efc9190614184565b905073ffffffffffffffffffffffffffffffffffffffff8616612f55576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610741565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610741565b612fb7858461403c565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611e79565b600081831061306d5781611e79565b5090919050565b606082471015613106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610741565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161312f91906141bf565b60006040518083038185875af1925050503d806000811461316c576040519150601f19603f3d011682016040523d82523d6000602084013e613171565b606091505b50915091506131828783838761318d565b979650505050505050565b6060831561322357825160000361321c5773ffffffffffffffffffffffffffffffffffffffff85163b61321c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610741565b50816129b1565b6129b183838151156132385781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074191906133a2565b5080546132789061389f565b6000825580601f10613288575050565b601f01602090049060005260206000209081019061187091905b808211156132b657600081556001016132a2565b5090565b6000602082840312156132cc57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611e7957600080fd5b803567ffffffffffffffff8116811461331457600080fd5b919050565b60006020828403121561332b57600080fd5b611e79826132fc565b60005b8381101561334f578181015183820152602001613337565b50506000910152565b60008151808452613370816020860160208601613334565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611e796020830184613358565b6000602082840312156133c757600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461187057600080fd5b8035613314816133ce565b60006020828403121561340d57600080fd5b8135611e79816133ce565b60006020828403121561342a57600080fd5b813567ffffffffffffffff81111561344157600080fd5b82016101008185031215611e7957600080fd5b60008083601f84011261346657600080fd5b50813567ffffffffffffffff81111561347e57600080fd5b6020830191508360208260051b850101111561349957600080fd5b9250929050565b600080600080604085870312156134b657600080fd5b843567ffffffffffffffff808211156134ce57600080fd5b6134da88838901613454565b909650945060208701359150808211156134f357600080fd5b5061350087828801613454565b95989497509550505050565b6000806040838503121561351f57600080fd5b823561352a816133ce565b946020939093013593505050565b60008060006040848603121561354d57600080fd5b613556846132fc565b9250602084013567ffffffffffffffff8082111561357357600080fd5b818601915086601f83011261358757600080fd5b81358181111561359657600080fd5b8760208285010111156135a857600080fd5b6020830194508093505050509250925092565b6000602082840312156135cd57600080fd5b813567ffffffffffffffff8111156135e457600080fd5b820160a08185031215611e7957600080fd5b6020815260008251604060208401526136126060840182613358565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261364d8282613358565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156136a457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613672565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156136a457835167ffffffffffffffff16835292840192918401916001016136cc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613745576137456136f2565b60405290565b60405160c0810167ffffffffffffffff81118282101715613745576137456136f2565b801515811461187057600080fd5b80356133148161376e565b80356fffffffffffffffffffffffffffffffff8116811461331457600080fd5b6000606082840312156137b957600080fd5b6040516060810181811067ffffffffffffffff821117156137dc576137dc6136f2565b60405290508082356137ed8161376e565b81526137fb60208401613787565b602082015261380c60408401613787565b60408201525092915050565b600080600060e0848603121561382d57600080fd5b613836846132fc565b925061384585602086016137a7565b915061385485608086016137a7565b90509250925092565b6000806020838503121561387057600080fd5b823567ffffffffffffffff81111561388757600080fd5b61389385828601613454565b90969095509350505050565b600181811c908216806138b357607f821691505b6020821081036138ec577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561390457600080fd5b5051919050565b600082601f83011261391c57600080fd5b813567ffffffffffffffff80821115613937576139376136f2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561397d5761397d6136f2565b8160405283815286602085880101111561399657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600061010082360312156139c957600080fd5b6139d1613721565b823567ffffffffffffffff808211156139e957600080fd5b6139f53683870161390b565b8352613a03602086016132fc565b6020840152613a14604086016133f0565b604084015260608501356060840152613a2f608086016133f0565b608084015260a0850135915080821115613a4857600080fd5b613a543683870161390b565b60a084015260c0850135915080821115613a6d57600080fd5b613a793683870161390b565b60c084015260e0850135915080821115613a9257600080fd5b50613a9f3682860161390b565b60e08301525092915050565b601f8211156112b8576000816000526020600020601f850160051c81016020861015613ad45750805b601f850160051c820191505b81811015613af357828155600101613ae0565b505050505050565b67ffffffffffffffff831115613b1357613b136136f2565b613b2783613b21835461389f565b83613aab565b6000601f841160018114613b795760008515613b435750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613c0f565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613bc85786850135825560209485019460019092019101613ba8565b5086821015613c03577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b604081526000613c296040830186613358565b82810360208401528381528385602083013760006020858301015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820101915050949350505050565b600060a08236031215613c8c57600080fd5b60405160a0810167ffffffffffffffff8282108183111715613cb057613cb06136f2565b816040528435915080821115613cc557600080fd5b50613cd23682860161390b565b825250613ce1602084016132fc565b60208201526040830135613cf4816133ce565b6040820152606083810135908201526080830135613d11816133ce565b608082015292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613d7f57600080fd5b9190910192915050565b60006101408236031215613d9c57600080fd5b613da461374b565b613dad836132fc565b8152613dbb6020840161377c565b6020820152604083013567ffffffffffffffff80821115613ddb57600080fd5b613de73683870161390b565b60408401526060850135915080821115613e0057600080fd5b50613e0d3682860161390b565b606083015250613e2036608085016137a7565b6080820152613e323660e085016137a7565b60a082015292915050565b815167ffffffffffffffff811115613e5757613e576136f2565b613e6b81613e65845461389f565b84613aab565b602080601f831160018114613ebe5760008415613e885750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613af3565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613f0b57888601518255948401946001909101908401613eec565b5085821015613f4757878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152613f7b81840187613358565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff9081166060870152908701511660808501529150613fb99050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e083015261364d565b60006020828403121561400257600080fd5b8151611e798161376e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561063c5761063c61400d565b67ffffffffffffffff8416815260e0810161409b60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c08301526129b1565b6060810161063c82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561412057600080fd5b8151611e79816133ce565b808202811582820484141761063c5761063c61400d565b8082018082111561063c5761063c61400d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826141ba577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008251613d7f81846020870161333456fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"localTokenDecimals\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRebalancer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"provideLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rebalancer\",\"type\":\"address\"}],\"name\":\"setRebalancer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101206040523480156200001257600080fd5b5060405162004f2338038062004f23833981016040819052620000359162000509565b8585858584336000816200005c57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008f576200008f8162000153565b50506001600160a01b0385161580620000af57506001600160a01b038116155b80620000c257506001600160a01b038216155b15620000e1576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0385811660805282811660c05260ff851660a052600480546001600160a01b031916918316919091179055825115801560e0526200013b576040805160008152602081019091526200013b9084620001cd565b50505050911515610100525062000693945050505050565b336001600160a01b038216036200017d57604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e051620001ee576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200027957600083828151811062000212576200021262000645565b602090810291909101015190506200022c6002826200032a565b156200026f576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101620001f1565b5060005b8151811015620003255760008282815181106200029e576200029e62000645565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002ca57506200031c565b620002d76002826200034a565b156200031a576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016200027d565b505050565b600062000341836001600160a01b03841662000361565b90505b92915050565b600062000341836001600160a01b03841662000465565b600081815260018301602052604081205480156200045a576000620003886001836200065b565b85549091506000906200039e906001906200065b565b90508082146200040a576000866000018281548110620003c257620003c262000645565b9060005260206000200154905080876000018481548110620003e857620003e862000645565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200041e576200041e6200067d565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000344565b600091505062000344565b6000818152600183016020526040812054620004ae5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000344565b50600062000344565b6001600160a01b0381168114620004cd57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b8051620004f381620004b7565b919050565b80518015158114620004f357600080fd5b60008060008060008060c087890312156200052357600080fd5b86516200053081620004b7565b8096505060208088015160ff811681146200054a57600080fd5b60408901519096506001600160401b03808211156200056857600080fd5b818a0191508a601f8301126200057d57600080fd5b815181811115620005925762000592620004d0565b8060051b604051601f19603f83011681018181108582111715620005ba57620005ba620004d0565b60405291825284820192508381018501918d831115620005d957600080fd5b938501935b828510156200060257620005f285620004e6565b84529385019392850192620005de565b8099505050505050506200061960608801620004e6565b92506200062960808801620004f8565b91506200063960a08801620004e6565b90509295509295509295565b634e487b7160e01b600052603260045260246000fd5b818103818111156200034457634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e051610100516147cd62000756600039600081816105a40152611ac601526000818161063e015281816121f10152612d0a01526000818161061801528181611e3501526124dd01526000818161036701528181610e6b01528181611fde01528181612098015281816120cc015281816120fd01526121440152600081816102ce015281816103230152818161077f015281816108510152818161094501528181611b8801528181612ca00152612ef501526147cd6000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c80638da5cb5b11610145578063c0d78655116100bd578063dc0bd9711161008c578063e8a1da1711610071578063e8a1da1714610662578063eb521a4c14610675578063f2fde38b1461068857600080fd5b8063dc0bd97114610616578063e0351e131461063c57600080fd5b8063c0d78655146105c8578063c4bffe2b146105db578063c75eea9c146105f0578063cf7401f31461060357600080fd5b8063acfecf9111610114578063b0f479a1116100f9578063b0f479a114610571578063b79465801461058f578063bb98546b146105a257600080fd5b8063acfecf91146104ef578063af58d59f1461050257600080fd5b80638da5cb5b1461047c5780639a4575b91461049a578063a42a7b8b146104ba578063a7cd63b7146104da57600080fd5b80634c5ef0ed116101d85780636cfd1553116101a757806379ba50971161018c57806379ba50971461044e5780637d54534e146104565780638926f54f1461046957600080fd5b80636cfd15531461041d5780636d3d1a581461043057600080fd5b80634c5ef0ed146103d157806354c8a4f3146103e457806362ddd3c4146103f7578063663200871461040a57600080fd5b8063240028e811610214578063240028e81461031357806324f65ee7146103605780633907753714610391578063432a6ba3146103b357600080fd5b806301ffc9a7146102465780630a861f2a1461026e578063181f5a771461028357806321df0da7146102cc575b600080fd5b6102596102543660046138bc565b61069b565b60405190151581526020015b60405180910390f35b61028161027c3660046138fe565b6106f7565b005b6102bf6040518060400160405280601a81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e352e3100000000000081525081565b6040516102659190613985565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102596103213660046139ba565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610265565b6103a461039f3660046139d7565b6108a8565b60405190518152602001610265565b600a5473ffffffffffffffffffffffffffffffffffffffff166102ee565b6102596103df366004613a30565b6109f6565b6102816103f2366004613aff565b610a40565b610281610405366004613a30565b610abb565b610281610418366004613b6b565b610b53565b61028161042b3660046139ba565b610c2f565b60095473ffffffffffffffffffffffffffffffffffffffff166102ee565b610281610c7e565b6102816104643660046139ba565b610d4c565b610259610477366004613b97565b610dcd565b60015473ffffffffffffffffffffffffffffffffffffffff166102ee565b6104ad6104a8366004613bb2565b610de4565b6040516102659190613bed565b6104cd6104c8366004613b97565b610eb0565b6040516102659190613c44565b6104e261101b565b6040516102659190613cc6565b6102816104fd366004613a30565b61102c565b610515610510366004613b97565b611144565b604051610265919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102ee565b6102bf61059d366004613b97565b611219565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102816105d63660046139ba565b6112c9565b6105e36113a4565b6040516102659190613d20565b6105156105fe366004613b97565b61145c565b610281610611366004613ea8565b61152e565b7f00000000000000000000000000000000000000000000000000000000000000006102ee565b7f0000000000000000000000000000000000000000000000000000000000000000610259565b610281610670366004613aff565b6115b2565b6102816106833660046138fe565b611ac4565b6102816106963660046139ba565b611be0565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fe1d405660000000000000000000000000000000000000000000000000000000014806106f157506106f182611bf4565b92915050565b600a5473ffffffffffffffffffffffffffffffffffffffff16331461074f576040517f8e4a23d60000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156107db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ff9190613eed565b1015610837576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61087873ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611cd8565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6040805160208101909152600081526108c082611dac565b600061091960608401356109146108da60c0870187613f06565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611fd092505050565b612094565b905061096c61092e60608501604086016139ba565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169083611cd8565b61097c60608401604085016139ba565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52836040516109da91815260200190565b60405180910390a3604080516020810190915290815292915050565b6000610a388383604051610a0b929190613f6b565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190612184565b949350505050565b610a4861219c565b610ab5848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920191909152506121ef92505050565b50505050565b610ac361219c565b610acc83610dcd565b610b0e576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610746565b610b4e8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506123a592505050565b505050565b610b5b61219c565b6040517f0a861f2a0000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff831690630a861f2a90602401600060405180830381600087803b158015610bc357600080fd5b505af1158015610bd7573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff167f6fa7abcf1345d1d478e5ea0da6b5f26a90eadb0546ef15ed3833944fbfd1db6282604051610c2391815260200190565b60405180910390a25050565b610c3761219c565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ccf576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610d5461219c565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b60006106f1600567ffffffffffffffff8416612184565b6040805180820190915260608082526020820152610e018261249f565b6040516060830135815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a26040518060400160405280610e5b84602001602081019061059d9190613b97565b8152602001610ea86040805160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260609101604051602081830303815290604052905090565b905292915050565b67ffffffffffffffff8116600090815260076020526040812060609190610ed99060050161262b565b90506000815167ffffffffffffffff811115610ef757610ef7613d62565b604051908082528060200260200182016040528015610f2a57816020015b6060815260200190600190039081610f155790505b50905060005b82518110156110135760086000848381518110610f4f57610f4f613f7b565b602002602001015181526020019081526020016000208054610f7090613faa565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9c90613faa565b8015610fe95780601f10610fbe57610100808354040283529160200191610fe9565b820191906000526020600020905b815481529060010190602001808311610fcc57829003601f168201915b505050505082828151811061100057611000613f7b565b6020908102919091010152600101610f30565b509392505050565b6060611027600261262b565b905090565b61103461219c565b61103d83610dcd565b61107f576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610746565b6110bf8282604051611092929190613f6b565b604080519182900390912067ffffffffffffffff8616600090815260076020529190912060050190612638565b6110fb578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161074693929190614046565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d76838360405161113792919061406a565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526106f190612644565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061124490613faa565b80601f016020809104026020016040519081016040528092919081815260200182805461127090613faa565b80156112bd5780601f10611292576101008083540402835291602001916112bd565b820191906000526020600020905b8154815290600101906020018083116112a057829003601f168201915b50505050509050919050565b6112d161219c565b73ffffffffffffffffffffffffffffffffffffffff811661131e576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684910160405180910390a15050565b606060006113b2600561262b565b90506000815167ffffffffffffffff8111156113d0576113d0613d62565b6040519080825280602002602001820160405280156113f9578160200160208202803683370190505b50905060005b82518110156114555782818151811061141a5761141a613f7b565b602002602001015182828151811061143457611434613f7b565b67ffffffffffffffff909216602092830291909101909101526001016113ff565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526106f190612644565b60095473ffffffffffffffffffffffffffffffffffffffff16331480159061156e575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156115a7576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610746565b610b4e8383836126f6565b6115ba61219c565b60005b838110156117a75760008585838181106115d9576115d9613f7b565b90506020020160208101906115ee9190613b97565b9050611605600567ffffffffffffffff8316612638565b611647576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610746565b67ffffffffffffffff8116600090815260076020526040812061166c9060050161262b565b905060005b81518110156116d8576116cf82828151811061168f5761168f613f7b565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161263890919063ffffffff16565b50600101611671565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611741600483018261384f565b60058201600081816117538282613889565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d85991694506020019250611795915050565b60405180910390a150506001016115bd565b5060005b81811015611abd5760008383838181106117c7576117c7613f7b565b90506020028101906117d9919061407e565b6117e29061414a565b90506117f3816060015160006127e0565b611802816080015160006127e0565b806040015151600003611841576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516118599060059067ffffffffffffffff1661291d565b61189e5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610746565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a909102999093161717909416959095179092559092029091176003820155908201516004820190611a2190826142c1565b5060005b826020015151811015611a6557611a5d836000015184602001518381518110611a5057611a50613f7b565b60200260200101516123a5565b600101611a25565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c28260000151836040015184606001518560800151604051611aab94939291906143db565b60405180910390a150506001016117ab565b5050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611b1b576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600a5473ffffffffffffffffffffffffffffffffffffffff163314611b6e576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610746565b611bb073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612929565b604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b611be861219c565b611bf181612987565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf000000000000000000000000000000000000000000000000000000001480611c8757507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806106f157507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610b4e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612a4b565b611dbf61032160a08301608084016139ba565b611e1e57611dd360a08201608083016139ba565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610746565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611e6a6040840160208501613b97565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611edb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eff9190614474565b15611f36576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f4e611f496040830160208401613b97565b612b57565b611f6e611f616040830160208401613b97565b6103df60a0840184613f06565b611fb357611f7f60a0820182613f06565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161074692919061406a565b611bf1611fc66040830160208401613b97565b8260600135612c7d565b6000815160000361200257507f0000000000000000000000000000000000000000000000000000000000000000919050565b815160201461203f57816040517f953576f70000000000000000000000000000000000000000000000000000000081526004016107469190613985565b6000828060200190518101906120559190613eed565b905060ff8111156106f157826040517f953576f70000000000000000000000000000000000000000000000000000000081526004016107469190613985565b60007f000000000000000000000000000000000000000000000000000000000000000060ff168260ff16036120ca5750816106f1565b7f000000000000000000000000000000000000000000000000000000000000000060ff168260ff16111561213e576121227f0000000000000000000000000000000000000000000000000000000000000000836144c0565b61212d90600a6145f9565b6121379084614608565b90506106f1565b612168827f00000000000000000000000000000000000000000000000000000000000000006144c0565b61217390600a6145f9565b61217d9084614643565b9392505050565b6000818152600183016020526040812054151561217d565b60015473ffffffffffffffffffffffffffffffffffffffff1633146121ed576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b7f0000000000000000000000000000000000000000000000000000000000000000612246576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156122dc57600083828151811061226657612266613f7b565b60200260200101519050612284816002612cc490919063ffffffff16565b156122d35760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101612249565b5060005b8151811015610b4e5760008282815181106122fd576122fd613f7b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612341575061239d565b61234c600282612ce6565b1561239b5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6001016122e0565b80516000036123e0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff8416600090815260079092526040909120612412906005018261291d565b61244c5782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161074692919061465a565b600081815260086020526040902061246483826142c1565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea836040516111379190613985565b6124b261032160a08301608084016139ba565b6124c657611dd360a08201608083016139ba565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb6125126040840160208501613b97565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015612583573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a79190614474565b156125de576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125f66125f160608301604084016139ba565b612d08565b61260e6126096040830160208401613b97565b612d87565b611bf16126216040830160208401613b97565b8260600135612ed5565b6060600061217d83612f19565b600061217d8383612f74565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526126d282606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426126b6919061467d565b85608001516fffffffffffffffffffffffffffffffff16613067565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6126ff83610dcd565b612741576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610746565b61274c8260006127e0565b67ffffffffffffffff8316600090815260076020526040902061276f908361308f565b61277a8160006127e0565b67ffffffffffffffff831660009081526007602052604090206127a0906002018261308f565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516127d393929190614690565b60405180910390a1505050565b8151156128ab5781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612836575060408201516fffffffffffffffffffffffffffffffff16155b1561286f57816040517f8020d1240000000000000000000000000000000000000000000000000000000081526004016107469190614713565b80156128a7576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff161515806128e4575060208201516fffffffffffffffffffffffffffffffff1615155b156128a757816040517fd68af9cc0000000000000000000000000000000000000000000000000000000081526004016107469190614713565b600061217d8383613231565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610ab59085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611d2a565b3373ffffffffffffffffffffffffffffffffffffffff8216036129d6576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000612aad826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166132809092919063ffffffff16565b805190915015610b4e5780806020019051810190612acb9190614474565b610b4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610746565b612b6081610dcd565b612ba2576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610746565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612c21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c459190614474565b611bf1576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610746565b67ffffffffffffffff821660009081526007602052604090206128a790600201827f000000000000000000000000000000000000000000000000000000000000000061328f565b600061217d8373ffffffffffffffffffffffffffffffffffffffff8416612f74565b600061217d8373ffffffffffffffffffffffffffffffffffffffff8416613231565b7f000000000000000000000000000000000000000000000000000000000000000015611bf157612d39600282613612565b611bf1576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610746565b612d9081610dcd565b612dd2576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610746565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612e4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e6f919061474f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611bf1576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610746565b67ffffffffffffffff821660009081526007602052604090206128a790827f000000000000000000000000000000000000000000000000000000000000000061328f565b6060816000018054806020026020016040519081016040528092919081815260200182805480156112bd57602002820191906000526020600020905b815481526020019060010190808311612f555750505050509050919050565b6000818152600183016020526040812054801561305d576000612f9860018361467d565b8554909150600090612fac9060019061467d565b9050808214613011576000866000018281548110612fcc57612fcc613f7b565b9060005260206000200154905080876000018481548110612fef57612fef613f7b565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806130225761302261476c565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106f1565b60009150506106f1565b6000613086856130778486614643565b613081908761479b565b613641565b95945050505050565b81546000906130b890700100000000000000000000000000000000900463ffffffff164261467d565b9050801561315a5760018301548354613100916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416613067565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354613180916fffffffffffffffffffffffffffffffff9081169116613641565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906127d3908490614713565b6000818152600183016020526040812054613278575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106f1565b5060006106f1565b6060610a388484600085613657565b825474010000000000000000000000000000000000000000900460ff1615806132b6575081155b156132c057505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061330690700100000000000000000000000000000000900463ffffffff164261467d565b905080156133c65781831115613348576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546133829083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16613067565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561347d5773ffffffffffffffffffffffffffffffffffffffff8416613425576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610746565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610746565b848310156135905760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906134c1908261467d565b6134cb878a61467d565b6134d5919061479b565b6134df9190614608565b905073ffffffffffffffffffffffffffffffffffffffff8616613538576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610746565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610746565b61359a858461467d565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561217d565b6000818310613650578161217d565b5090919050565b6060824710156136e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610746565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161371291906147ae565b60006040518083038185875af1925050503d806000811461374f576040519150601f19603f3d011682016040523d82523d6000602084013e613754565b606091505b509150915061376587838387613770565b979650505050505050565b606083156138065782516000036137ff5773ffffffffffffffffffffffffffffffffffffffff85163b6137ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610746565b5081610a38565b610a38838381511561381b5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107469190613985565b50805461385b90613faa565b6000825580601f1061386b575050565b601f016020900490600052602060002090810190611bf191906138a3565b5080546000825590600052602060002090810190611bf191905b5b808211156138b857600081556001016138a4565b5090565b6000602082840312156138ce57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461217d57600080fd5b60006020828403121561391057600080fd5b5035919050565b60005b8381101561393257818101518382015260200161391a565b50506000910152565b60008151808452613953816020860160208601613917565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061217d602083018461393b565b73ffffffffffffffffffffffffffffffffffffffff81168114611bf157600080fd5b6000602082840312156139cc57600080fd5b813561217d81613998565b6000602082840312156139e957600080fd5b813567ffffffffffffffff811115613a0057600080fd5b8201610100818503121561217d57600080fd5b803567ffffffffffffffff81168114613a2b57600080fd5b919050565b600080600060408486031215613a4557600080fd5b613a4e84613a13565b9250602084013567ffffffffffffffff80821115613a6b57600080fd5b818601915086601f830112613a7f57600080fd5b813581811115613a8e57600080fd5b876020828501011115613aa057600080fd5b6020830194508093505050509250925092565b60008083601f840112613ac557600080fd5b50813567ffffffffffffffff811115613add57600080fd5b6020830191508360208260051b8501011115613af857600080fd5b9250929050565b60008060008060408587031215613b1557600080fd5b843567ffffffffffffffff80821115613b2d57600080fd5b613b3988838901613ab3565b90965094506020870135915080821115613b5257600080fd5b50613b5f87828801613ab3565b95989497509550505050565b60008060408385031215613b7e57600080fd5b8235613b8981613998565b946020939093013593505050565b600060208284031215613ba957600080fd5b61217d82613a13565b600060208284031215613bc457600080fd5b813567ffffffffffffffff811115613bdb57600080fd5b820160a0818503121561217d57600080fd5b602081526000825160406020840152613c09606084018261393b565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152613086828261393b565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613cb9577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452613ca785835161393b565b94509285019290850190600101613c6d565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613d1457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613ce2565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613d1457835167ffffffffffffffff1683529284019291840191600101613d3c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613db457613db4613d62565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613e0157613e01613d62565b604052919050565b8015158114611bf157600080fd5b80356fffffffffffffffffffffffffffffffff81168114613a2b57600080fd5b600060608284031215613e4957600080fd5b6040516060810181811067ffffffffffffffff82111715613e6c57613e6c613d62565b6040529050808235613e7d81613e09565b8152613e8b60208401613e17565b6020820152613e9c60408401613e17565b60408201525092915050565b600080600060e08486031215613ebd57600080fd5b613ec684613a13565b9250613ed58560208601613e37565b9150613ee48560808601613e37565b90509250925092565b600060208284031215613eff57600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f3b57600080fd5b83018035915067ffffffffffffffff821115613f5657600080fd5b602001915036819003821315613af857600080fd5b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c90821680613fbe57607f821691505b602082108103613ff7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b67ffffffffffffffff84168152604060208201526000613086604083018486613ffd565b602081526000610a38602083018486613ffd565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee18336030181126140b257600080fd5b9190910192915050565b600082601f8301126140cd57600080fd5b813567ffffffffffffffff8111156140e7576140e7613d62565b61411860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613dba565b81815284602083860101111561412d57600080fd5b816020850160208301376000918101602001919091529392505050565b6000610120823603121561415d57600080fd5b614165613d91565b61416e83613a13565b815260208084013567ffffffffffffffff8082111561418c57600080fd5b9085019036601f83011261419f57600080fd5b8135818111156141b1576141b1613d62565b8060051b6141c0858201613dba565b91825283810185019185810190368411156141da57600080fd5b86860192505b83831015614216578235858111156141f85760008081fd5b6142063689838a01016140bc565b83525091860191908601906141e0565b808789015250505050604086013592508083111561423357600080fd5b5050614241368286016140bc565b6040830152506142543660608501613e37565b60608201526142663660c08501613e37565b608082015292915050565b601f821115610b4e576000816000526020600020601f850160051c8101602086101561429a5750805b601f850160051c820191505b818110156142b9578281556001016142a6565b505050505050565b815167ffffffffffffffff8111156142db576142db613d62565b6142ef816142e98454613faa565b84614271565b602080601f831160018114614342576000841561430c5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556142b9565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561438f57888601518255948401946001909101908401614370565b50858210156143cb57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526143ff8184018761393b565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff908116606087015290870151166080850152915061443d9050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613086565b60006020828403121561448657600080fd5b815161217d81613e09565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff82811682821603908111156106f1576106f1614491565b600181815b8085111561453257817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561451857614518614491565b8085161561452557918102915b93841c93908002906144de565b509250929050565b600082614549575060016106f1565b81614556575060006106f1565b816001811461456c576002811461457657614592565b60019150506106f1565b60ff84111561458757614587614491565b50506001821b6106f1565b5060208310610133831016604e8410600b84101617156145b5575081810a6106f1565b6145bf83836144d9565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156145f1576145f1614491565b029392505050565b600061217d60ff84168361453a565b60008261463e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176106f1576106f1614491565b67ffffffffffffffff83168152604060208201526000610a38604083018461393b565b818103818111156106f1576106f1614491565b67ffffffffffffffff8416815260e081016146dc60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610a38565b606081016106f182848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561476157600080fd5b815161217d81613998565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b808201808211156106f1576106f1614491565b600082516140b281846020870161391756fea164736f6c6343000818000a", } var LockReleaseTokenPoolABI = LockReleaseTokenPoolMetaData.ABI var LockReleaseTokenPoolBin = LockReleaseTokenPoolMetaData.Bin -func DeployLockReleaseTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, allowlist []common.Address, rmnProxy common.Address, acceptLiquidity bool, router common.Address) (common.Address, *types.Transaction, *LockReleaseTokenPool, error) { +func DeployLockReleaseTokenPool(auth *bind.TransactOpts, backend bind.ContractBackend, token common.Address, localTokenDecimals uint8, allowlist []common.Address, rmnProxy common.Address, acceptLiquidity bool, router common.Address) (common.Address, *types.Transaction, *LockReleaseTokenPool, error) { parsed, err := LockReleaseTokenPoolMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -99,7 +98,7 @@ func DeployLockReleaseTokenPool(auth *bind.TransactOpts, backend bind.ContractBa return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LockReleaseTokenPoolBin), backend, token, allowlist, rmnProxy, acceptLiquidity, router) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(LockReleaseTokenPoolBin), backend, token, localTokenDecimals, allowlist, rmnProxy, acceptLiquidity, router) if err != nil { return common.Address{}, nil, nil, err } @@ -376,26 +375,26 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetRebalancer() return _LockReleaseTokenPool.Contract.GetRebalancer(&_LockReleaseTokenPool.CallOpts) } -func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetRemotePools(opts *bind.CallOpts, remoteChainSelector uint64) ([][]byte, error) { var out []interface{} - err := _LockReleaseTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getRemotePools", remoteChainSelector) if err != nil { - return *new([]byte), err + return *new([][]byte), err } - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + out0 := *abi.ConvertType(out[0], new([][]byte)).(*[][]byte) return out0, err } -func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { - return _LockReleaseTokenPool.Contract.GetRemotePool(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetRemotePools(remoteChainSelector uint64) ([][]byte, error) { + return _LockReleaseTokenPool.Contract.GetRemotePools(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) } -func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { - return _LockReleaseTokenPool.Contract.GetRemotePool(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetRemotePools(remoteChainSelector uint64) ([][]byte, error) { + return _LockReleaseTokenPool.Contract.GetRemotePools(&_LockReleaseTokenPool.CallOpts, remoteChainSelector) } func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { @@ -508,6 +507,50 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetToken() (comm return _LockReleaseTokenPool.Contract.GetToken(&_LockReleaseTokenPool.CallOpts) } +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) GetTokenDecimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "getTokenDecimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) GetTokenDecimals() (uint8, error) { + return _LockReleaseTokenPool.Contract.GetTokenDecimals(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) GetTokenDecimals() (uint8, error) { + return _LockReleaseTokenPool.Contract.GetTokenDecimals(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) IsRemotePool(opts *bind.CallOpts, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "isRemotePool", remoteChainSelector, remotePoolAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) IsRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + return _LockReleaseTokenPool.Contract.IsRemotePool(&_LockReleaseTokenPool.CallOpts, remoteChainSelector, remotePoolAddress) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) IsRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + return _LockReleaseTokenPool.Contract.IsRemotePool(&_LockReleaseTokenPool.CallOpts, remoteChainSelector, remotePoolAddress) +} + func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { var out []interface{} err := _LockReleaseTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) @@ -630,6 +673,18 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) AcceptOwners return _LockReleaseTokenPool.Contract.AcceptOwnership(&_LockReleaseTokenPool.TransactOpts) } +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) AddRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "addRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) AddRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.AddRemotePool(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) AddRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.AddRemotePool(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { return _LockReleaseTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) } @@ -642,16 +697,16 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ApplyAllowLi return _LockReleaseTokenPool.Contract.ApplyAllowListUpdates(&_LockReleaseTokenPool.TransactOpts, removes, adds) } -func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _LockReleaseTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "applyChainUpdates", remoteChainSelectorsToRemove, chainsToAdd) } -func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _LockReleaseTokenPool.Contract.ApplyChainUpdates(&_LockReleaseTokenPool.TransactOpts, chains) +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) ApplyChainUpdates(remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyChainUpdates(&_LockReleaseTokenPool.TransactOpts, remoteChainSelectorsToRemove, chainsToAdd) } -func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _LockReleaseTokenPool.Contract.ApplyChainUpdates(&_LockReleaseTokenPool.TransactOpts, chains) +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ApplyChainUpdates(remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.ApplyChainUpdates(&_LockReleaseTokenPool.TransactOpts, remoteChainSelectorsToRemove, chainsToAdd) } func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { @@ -690,6 +745,18 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) ReleaseOrMin return _LockReleaseTokenPool.Contract.ReleaseOrMint(&_LockReleaseTokenPool.TransactOpts, releaseOrMintIn) } +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) RemoveRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.contract.Transact(opts, "removeRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) RemoveRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.RemoveRemotePool(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) RemoveRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _LockReleaseTokenPool.Contract.RemoveRemotePool(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { return _LockReleaseTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) } @@ -726,18 +793,6 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetRebalance return _LockReleaseTokenPool.Contract.SetRebalancer(&_LockReleaseTokenPool.TransactOpts, rebalancer) } -func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _LockReleaseTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) -} - -func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _LockReleaseTokenPool.Contract.SetRemotePool(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) -} - -func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _LockReleaseTokenPool.Contract.SetRemotePool(&_LockReleaseTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) -} - func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { return _LockReleaseTokenPool.contract.Transact(opts, "setRouter", newRouter) } @@ -2812,8 +2867,136 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseReleased(log typ return event, nil } -type LockReleaseTokenPoolRemotePoolSetIterator struct { - Event *LockReleaseTokenPoolRemotePoolSet +type LockReleaseTokenPoolRemotePoolAddedIterator struct { + Event *LockReleaseTokenPoolRemotePoolAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *LockReleaseTokenPoolRemotePoolAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolRemotePoolAdded) + 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 + } + } + + select { + case log := <-it.logs: + it.Event = new(LockReleaseTokenPoolRemotePoolAdded) + 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() + } +} + +func (it *LockReleaseTokenPoolRemotePoolAddedIterator) Error() error { + return it.fail +} + +func (it *LockReleaseTokenPoolRemotePoolAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type LockReleaseTokenPoolRemotePoolAdded struct { + RemoteChainSelector uint64 + RemotePoolAddress []byte + Raw types.Log +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterRemotePoolAdded(opts *bind.FilterOpts, remoteChainSelector []uint64) (*LockReleaseTokenPoolRemotePoolAddedIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "RemotePoolAdded", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &LockReleaseTokenPoolRemotePoolAddedIterator{contract: _LockReleaseTokenPool.contract, event: "RemotePoolAdded", logs: logs, sub: sub}, nil +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchRemotePoolAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolRemotePoolAdded, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "RemotePoolAdded", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(LockReleaseTokenPoolRemotePoolAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "RemotePoolAdded", 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 +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseRemotePoolAdded(log types.Log) (*LockReleaseTokenPoolRemotePoolAdded, error) { + event := new(LockReleaseTokenPoolRemotePoolAdded) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "RemotePoolAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type LockReleaseTokenPoolRemotePoolRemovedIterator struct { + Event *LockReleaseTokenPoolRemotePoolRemoved contract *bind.BoundContract event string @@ -2824,7 +3007,7 @@ type LockReleaseTokenPoolRemotePoolSetIterator struct { fail error } -func (it *LockReleaseTokenPoolRemotePoolSetIterator) Next() bool { +func (it *LockReleaseTokenPoolRemotePoolRemovedIterator) Next() bool { if it.fail != nil { return false @@ -2833,7 +3016,7 @@ func (it *LockReleaseTokenPoolRemotePoolSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(LockReleaseTokenPoolRemotePoolSet) + it.Event = new(LockReleaseTokenPoolRemotePoolRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2848,7 +3031,7 @@ func (it *LockReleaseTokenPoolRemotePoolSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(LockReleaseTokenPoolRemotePoolSet) + it.Event = new(LockReleaseTokenPoolRemotePoolRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2863,44 +3046,43 @@ func (it *LockReleaseTokenPoolRemotePoolSetIterator) Next() bool { } } -func (it *LockReleaseTokenPoolRemotePoolSetIterator) Error() error { +func (it *LockReleaseTokenPoolRemotePoolRemovedIterator) Error() error { return it.fail } -func (it *LockReleaseTokenPoolRemotePoolSetIterator) Close() error { +func (it *LockReleaseTokenPoolRemotePoolRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -type LockReleaseTokenPoolRemotePoolSet struct { +type LockReleaseTokenPoolRemotePoolRemoved struct { RemoteChainSelector uint64 - PreviousPoolAddress []byte RemotePoolAddress []byte Raw types.Log } -func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*LockReleaseTokenPoolRemotePoolSetIterator, error) { +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) FilterRemotePoolRemoved(opts *bind.FilterOpts, remoteChainSelector []uint64) (*LockReleaseTokenPoolRemotePoolRemovedIterator, error) { var remoteChainSelectorRule []interface{} for _, remoteChainSelectorItem := range remoteChainSelector { remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + logs, sub, err := _LockReleaseTokenPool.contract.FilterLogs(opts, "RemotePoolRemoved", remoteChainSelectorRule) if err != nil { return nil, err } - return &LockReleaseTokenPoolRemotePoolSetIterator{contract: _LockReleaseTokenPool.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil + return &LockReleaseTokenPoolRemotePoolRemovedIterator{contract: _LockReleaseTokenPool.contract, event: "RemotePoolRemoved", logs: logs, sub: sub}, nil } -func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchRemotePoolRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolRemotePoolRemoved, remoteChainSelector []uint64) (event.Subscription, error) { var remoteChainSelectorRule []interface{} for _, remoteChainSelectorItem := range remoteChainSelector { remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + logs, sub, err := _LockReleaseTokenPool.contract.WatchLogs(opts, "RemotePoolRemoved", remoteChainSelectorRule) if err != nil { return nil, err } @@ -2910,8 +3092,8 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchRemotePoolSet(op select { case log := <-logs: - event := new(LockReleaseTokenPoolRemotePoolSet) - if err := _LockReleaseTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + event := new(LockReleaseTokenPoolRemotePoolRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "RemotePoolRemoved", log); err != nil { return err } event.Raw = log @@ -2932,9 +3114,9 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) WatchRemotePoolSet(op }), nil } -func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseRemotePoolSet(log types.Log) (*LockReleaseTokenPoolRemotePoolSet, error) { - event := new(LockReleaseTokenPoolRemotePoolSet) - if err := _LockReleaseTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { +func (_LockReleaseTokenPool *LockReleaseTokenPoolFilterer) ParseRemotePoolRemoved(log types.Log) (*LockReleaseTokenPoolRemotePoolRemoved, error) { + event := new(LockReleaseTokenPoolRemotePoolRemoved) + if err := _LockReleaseTokenPool.contract.UnpackLog(event, "RemotePoolRemoved", log); err != nil { return nil, err } event.Raw = log @@ -3210,8 +3392,10 @@ func (_LockReleaseTokenPool *LockReleaseTokenPool) ParseLog(log types.Log) (gene return _LockReleaseTokenPool.ParseRateLimitAdminSet(log) case _LockReleaseTokenPool.abi.Events["Released"].ID: return _LockReleaseTokenPool.ParseReleased(log) - case _LockReleaseTokenPool.abi.Events["RemotePoolSet"].ID: - return _LockReleaseTokenPool.ParseRemotePoolSet(log) + case _LockReleaseTokenPool.abi.Events["RemotePoolAdded"].ID: + return _LockReleaseTokenPool.ParseRemotePoolAdded(log) + case _LockReleaseTokenPool.abi.Events["RemotePoolRemoved"].ID: + return _LockReleaseTokenPool.ParseRemotePoolRemoved(log) case _LockReleaseTokenPool.abi.Events["RouterUpdated"].ID: return _LockReleaseTokenPool.ParseRouterUpdated(log) case _LockReleaseTokenPool.abi.Events["TokensConsumed"].ID: @@ -3286,8 +3470,12 @@ func (LockReleaseTokenPoolReleased) Topic() common.Hash { return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") } -func (LockReleaseTokenPoolRemotePoolSet) Topic() common.Hash { - return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +func (LockReleaseTokenPoolRemotePoolAdded) Topic() common.Hash { + return common.HexToHash("0x7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea") +} + +func (LockReleaseTokenPoolRemotePoolRemoved) Topic() common.Hash { + return common.HexToHash("0x52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d76") } func (LockReleaseTokenPoolRouterUpdated) Topic() common.Hash { @@ -3317,7 +3505,7 @@ type LockReleaseTokenPoolInterface interface { GetRebalancer(opts *bind.CallOpts) (common.Address, error) - GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + GetRemotePools(opts *bind.CallOpts, remoteChainSelector uint64) ([][]byte, error) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) @@ -3329,6 +3517,10 @@ type LockReleaseTokenPoolInterface interface { GetToken(opts *bind.CallOpts) (common.Address, error) + GetTokenDecimals(opts *bind.CallOpts) (uint8, error) + + IsRemotePool(opts *bind.CallOpts, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) @@ -3341,9 +3533,11 @@ type LockReleaseTokenPoolInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + AddRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) - ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + ApplyChainUpdates(opts *bind.TransactOpts, remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) @@ -3351,14 +3545,14 @@ type LockReleaseTokenPoolInterface interface { ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + RemoveRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) SetRebalancer(opts *bind.TransactOpts, rebalancer common.Address) (*types.Transaction, error) - SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) - SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) TransferLiquidity(opts *bind.TransactOpts, from common.Address, amount *big.Int) (*types.Transaction, error) @@ -3463,11 +3657,17 @@ type LockReleaseTokenPoolInterface interface { ParseReleased(log types.Log) (*LockReleaseTokenPoolReleased, error) - FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*LockReleaseTokenPoolRemotePoolSetIterator, error) + FilterRemotePoolAdded(opts *bind.FilterOpts, remoteChainSelector []uint64) (*LockReleaseTokenPoolRemotePoolAddedIterator, error) + + WatchRemotePoolAdded(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolRemotePoolAdded, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolAdded(log types.Log) (*LockReleaseTokenPoolRemotePoolAdded, error) + + FilterRemotePoolRemoved(opts *bind.FilterOpts, remoteChainSelector []uint64) (*LockReleaseTokenPoolRemotePoolRemovedIterator, error) - WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + WatchRemotePoolRemoved(opts *bind.WatchOpts, sink chan<- *LockReleaseTokenPoolRemotePoolRemoved, remoteChainSelector []uint64) (event.Subscription, error) - ParseRemotePoolSet(log types.Log) (*LockReleaseTokenPoolRemotePoolSet, error) + ParseRemotePoolRemoved(log types.Log) (*LockReleaseTokenPoolRemotePoolRemoved, error) FilterRouterUpdated(opts *bind.FilterOpts) (*LockReleaseTokenPoolRouterUpdatedIterator, error) diff --git a/core/gethwrappers/ccip/generated/token_pool/token_pool.go b/core/gethwrappers/ccip/generated/token_pool/token_pool.go index 3465ff76fe0..af6333e22d3 100644 --- a/core/gethwrappers/ccip/generated/token_pool/token_pool.go +++ b/core/gethwrappers/ccip/generated/token_pool/token_pool.go @@ -74,15 +74,14 @@ type RateLimiterTokenBucket struct { type TokenPoolChainUpdate struct { RemoteChainSelector uint64 - Allowed bool - RemotePoolAddress []byte + RemotePoolAddresses [][]byte RemoteTokenAddress []byte OutboundRateLimiterConfig RateLimiterConfig InboundRateLimiterConfig RateLimiterConfig } var TokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"lockOrBurnOut\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"lockOrBurnOut\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } var TokenPoolABI = TokenPoolMetaData.ABI @@ -313,26 +312,26 @@ func (_TokenPool *TokenPoolCallerSession) GetRateLimitAdmin() (common.Address, e return _TokenPool.Contract.GetRateLimitAdmin(&_TokenPool.CallOpts) } -func (_TokenPool *TokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { +func (_TokenPool *TokenPoolCaller) GetRemotePools(opts *bind.CallOpts, remoteChainSelector uint64) ([][]byte, error) { var out []interface{} - err := _TokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + err := _TokenPool.contract.Call(opts, &out, "getRemotePools", remoteChainSelector) if err != nil { - return *new([]byte), err + return *new([][]byte), err } - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + out0 := *abi.ConvertType(out[0], new([][]byte)).(*[][]byte) return out0, err } -func (_TokenPool *TokenPoolSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { - return _TokenPool.Contract.GetRemotePool(&_TokenPool.CallOpts, remoteChainSelector) +func (_TokenPool *TokenPoolSession) GetRemotePools(remoteChainSelector uint64) ([][]byte, error) { + return _TokenPool.Contract.GetRemotePools(&_TokenPool.CallOpts, remoteChainSelector) } -func (_TokenPool *TokenPoolCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { - return _TokenPool.Contract.GetRemotePool(&_TokenPool.CallOpts, remoteChainSelector) +func (_TokenPool *TokenPoolCallerSession) GetRemotePools(remoteChainSelector uint64) ([][]byte, error) { + return _TokenPool.Contract.GetRemotePools(&_TokenPool.CallOpts, remoteChainSelector) } func (_TokenPool *TokenPoolCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { @@ -445,6 +444,50 @@ func (_TokenPool *TokenPoolCallerSession) GetToken() (common.Address, error) { return _TokenPool.Contract.GetToken(&_TokenPool.CallOpts) } +func (_TokenPool *TokenPoolCaller) GetTokenDecimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "getTokenDecimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) GetTokenDecimals() (uint8, error) { + return _TokenPool.Contract.GetTokenDecimals(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCallerSession) GetTokenDecimals() (uint8, error) { + return _TokenPool.Contract.GetTokenDecimals(&_TokenPool.CallOpts) +} + +func (_TokenPool *TokenPoolCaller) IsRemotePool(opts *bind.CallOpts, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + var out []interface{} + err := _TokenPool.contract.Call(opts, &out, "isRemotePool", remoteChainSelector, remotePoolAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_TokenPool *TokenPoolSession) IsRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + return _TokenPool.Contract.IsRemotePool(&_TokenPool.CallOpts, remoteChainSelector, remotePoolAddress) +} + +func (_TokenPool *TokenPoolCallerSession) IsRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + return _TokenPool.Contract.IsRemotePool(&_TokenPool.CallOpts, remoteChainSelector, remotePoolAddress) +} + func (_TokenPool *TokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { var out []interface{} err := _TokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) @@ -545,6 +588,18 @@ func (_TokenPool *TokenPoolTransactorSession) AcceptOwnership() (*types.Transact return _TokenPool.Contract.AcceptOwnership(&_TokenPool.TransactOpts) } +func (_TokenPool *TokenPoolTransactor) AddRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "addRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_TokenPool *TokenPoolSession) AddRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _TokenPool.Contract.AddRemotePool(&_TokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_TokenPool *TokenPoolTransactorSession) AddRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _TokenPool.Contract.AddRemotePool(&_TokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + func (_TokenPool *TokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { return _TokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) } @@ -557,16 +612,16 @@ func (_TokenPool *TokenPoolTransactorSession) ApplyAllowListUpdates(removes []co return _TokenPool.Contract.ApplyAllowListUpdates(&_TokenPool.TransactOpts, removes, adds) } -func (_TokenPool *TokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _TokenPool.contract.Transact(opts, "applyChainUpdates", chains) +func (_TokenPool *TokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "applyChainUpdates", remoteChainSelectorsToRemove, chainsToAdd) } -func (_TokenPool *TokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _TokenPool.Contract.ApplyChainUpdates(&_TokenPool.TransactOpts, chains) +func (_TokenPool *TokenPoolSession) ApplyChainUpdates(remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _TokenPool.Contract.ApplyChainUpdates(&_TokenPool.TransactOpts, remoteChainSelectorsToRemove, chainsToAdd) } -func (_TokenPool *TokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _TokenPool.Contract.ApplyChainUpdates(&_TokenPool.TransactOpts, chains) +func (_TokenPool *TokenPoolTransactorSession) ApplyChainUpdates(remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _TokenPool.Contract.ApplyChainUpdates(&_TokenPool.TransactOpts, remoteChainSelectorsToRemove, chainsToAdd) } func (_TokenPool *TokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { @@ -593,6 +648,18 @@ func (_TokenPool *TokenPoolTransactorSession) ReleaseOrMint(releaseOrMintIn Pool return _TokenPool.Contract.ReleaseOrMint(&_TokenPool.TransactOpts, releaseOrMintIn) } +func (_TokenPool *TokenPoolTransactor) RemoveRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _TokenPool.contract.Transact(opts, "removeRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_TokenPool *TokenPoolSession) RemoveRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _TokenPool.Contract.RemoveRemotePool(&_TokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_TokenPool *TokenPoolTransactorSession) RemoveRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _TokenPool.Contract.RemoveRemotePool(&_TokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + func (_TokenPool *TokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { return _TokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) } @@ -617,18 +684,6 @@ func (_TokenPool *TokenPoolTransactorSession) SetRateLimitAdmin(rateLimitAdmin c return _TokenPool.Contract.SetRateLimitAdmin(&_TokenPool.TransactOpts, rateLimitAdmin) } -func (_TokenPool *TokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _TokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) -} - -func (_TokenPool *TokenPoolSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _TokenPool.Contract.SetRemotePool(&_TokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) -} - -func (_TokenPool *TokenPoolTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _TokenPool.Contract.SetRemotePool(&_TokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) -} - func (_TokenPool *TokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { return _TokenPool.contract.Transact(opts, "setRouter", newRouter) } @@ -2279,8 +2334,136 @@ func (_TokenPool *TokenPoolFilterer) ParseReleased(log types.Log) (*TokenPoolRel return event, nil } -type TokenPoolRemotePoolSetIterator struct { - Event *TokenPoolRemotePoolSet +type TokenPoolRemotePoolAddedIterator struct { + Event *TokenPoolRemotePoolAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *TokenPoolRemotePoolAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenPoolRemotePoolAdded) + 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 + } + } + + select { + case log := <-it.logs: + it.Event = new(TokenPoolRemotePoolAdded) + 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() + } +} + +func (it *TokenPoolRemotePoolAddedIterator) Error() error { + return it.fail +} + +func (it *TokenPoolRemotePoolAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type TokenPoolRemotePoolAdded struct { + RemoteChainSelector uint64 + RemotePoolAddress []byte + Raw types.Log +} + +func (_TokenPool *TokenPoolFilterer) FilterRemotePoolAdded(opts *bind.FilterOpts, remoteChainSelector []uint64) (*TokenPoolRemotePoolAddedIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "RemotePoolAdded", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &TokenPoolRemotePoolAddedIterator{contract: _TokenPool.contract, event: "RemotePoolAdded", logs: logs, sub: sub}, nil +} + +func (_TokenPool *TokenPoolFilterer) WatchRemotePoolAdded(opts *bind.WatchOpts, sink chan<- *TokenPoolRemotePoolAdded, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "RemotePoolAdded", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(TokenPoolRemotePoolAdded) + if err := _TokenPool.contract.UnpackLog(event, "RemotePoolAdded", 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 +} + +func (_TokenPool *TokenPoolFilterer) ParseRemotePoolAdded(log types.Log) (*TokenPoolRemotePoolAdded, error) { + event := new(TokenPoolRemotePoolAdded) + if err := _TokenPool.contract.UnpackLog(event, "RemotePoolAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type TokenPoolRemotePoolRemovedIterator struct { + Event *TokenPoolRemotePoolRemoved contract *bind.BoundContract event string @@ -2291,7 +2474,7 @@ type TokenPoolRemotePoolSetIterator struct { fail error } -func (it *TokenPoolRemotePoolSetIterator) Next() bool { +func (it *TokenPoolRemotePoolRemovedIterator) Next() bool { if it.fail != nil { return false @@ -2300,7 +2483,7 @@ func (it *TokenPoolRemotePoolSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(TokenPoolRemotePoolSet) + it.Event = new(TokenPoolRemotePoolRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2315,7 +2498,7 @@ func (it *TokenPoolRemotePoolSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(TokenPoolRemotePoolSet) + it.Event = new(TokenPoolRemotePoolRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2330,44 +2513,43 @@ func (it *TokenPoolRemotePoolSetIterator) Next() bool { } } -func (it *TokenPoolRemotePoolSetIterator) Error() error { +func (it *TokenPoolRemotePoolRemovedIterator) Error() error { return it.fail } -func (it *TokenPoolRemotePoolSetIterator) Close() error { +func (it *TokenPoolRemotePoolRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -type TokenPoolRemotePoolSet struct { +type TokenPoolRemotePoolRemoved struct { RemoteChainSelector uint64 - PreviousPoolAddress []byte RemotePoolAddress []byte Raw types.Log } -func (_TokenPool *TokenPoolFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*TokenPoolRemotePoolSetIterator, error) { +func (_TokenPool *TokenPoolFilterer) FilterRemotePoolRemoved(opts *bind.FilterOpts, remoteChainSelector []uint64) (*TokenPoolRemotePoolRemovedIterator, error) { var remoteChainSelectorRule []interface{} for _, remoteChainSelectorItem := range remoteChainSelector { remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _TokenPool.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + logs, sub, err := _TokenPool.contract.FilterLogs(opts, "RemotePoolRemoved", remoteChainSelectorRule) if err != nil { return nil, err } - return &TokenPoolRemotePoolSetIterator{contract: _TokenPool.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil + return &TokenPoolRemotePoolRemovedIterator{contract: _TokenPool.contract, event: "RemotePoolRemoved", logs: logs, sub: sub}, nil } -func (_TokenPool *TokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *TokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { +func (_TokenPool *TokenPoolFilterer) WatchRemotePoolRemoved(opts *bind.WatchOpts, sink chan<- *TokenPoolRemotePoolRemoved, remoteChainSelector []uint64) (event.Subscription, error) { var remoteChainSelectorRule []interface{} for _, remoteChainSelectorItem := range remoteChainSelector { remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _TokenPool.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + logs, sub, err := _TokenPool.contract.WatchLogs(opts, "RemotePoolRemoved", remoteChainSelectorRule) if err != nil { return nil, err } @@ -2377,8 +2559,8 @@ func (_TokenPool *TokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, si select { case log := <-logs: - event := new(TokenPoolRemotePoolSet) - if err := _TokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + event := new(TokenPoolRemotePoolRemoved) + if err := _TokenPool.contract.UnpackLog(event, "RemotePoolRemoved", log); err != nil { return err } event.Raw = log @@ -2399,9 +2581,9 @@ func (_TokenPool *TokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, si }), nil } -func (_TokenPool *TokenPoolFilterer) ParseRemotePoolSet(log types.Log) (*TokenPoolRemotePoolSet, error) { - event := new(TokenPoolRemotePoolSet) - if err := _TokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { +func (_TokenPool *TokenPoolFilterer) ParseRemotePoolRemoved(log types.Log) (*TokenPoolRemotePoolRemoved, error) { + event := new(TokenPoolRemotePoolRemoved) + if err := _TokenPool.contract.UnpackLog(event, "RemotePoolRemoved", log); err != nil { return nil, err } event.Raw = log @@ -2554,8 +2736,10 @@ func (_TokenPool *TokenPool) ParseLog(log types.Log) (generated.AbigenLog, error return _TokenPool.ParseRateLimitAdminSet(log) case _TokenPool.abi.Events["Released"].ID: return _TokenPool.ParseReleased(log) - case _TokenPool.abi.Events["RemotePoolSet"].ID: - return _TokenPool.ParseRemotePoolSet(log) + case _TokenPool.abi.Events["RemotePoolAdded"].ID: + return _TokenPool.ParseRemotePoolAdded(log) + case _TokenPool.abi.Events["RemotePoolRemoved"].ID: + return _TokenPool.ParseRemotePoolRemoved(log) case _TokenPool.abi.Events["RouterUpdated"].ID: return _TokenPool.ParseRouterUpdated(log) @@ -2616,8 +2800,12 @@ func (TokenPoolReleased) Topic() common.Hash { return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") } -func (TokenPoolRemotePoolSet) Topic() common.Hash { - return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +func (TokenPoolRemotePoolAdded) Topic() common.Hash { + return common.HexToHash("0x7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea") +} + +func (TokenPoolRemotePoolRemoved) Topic() common.Hash { + return common.HexToHash("0x52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d76") } func (TokenPoolRouterUpdated) Topic() common.Hash { @@ -2639,7 +2827,7 @@ type TokenPoolInterface interface { GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) - GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + GetRemotePools(opts *bind.CallOpts, remoteChainSelector uint64) ([][]byte, error) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) @@ -2651,6 +2839,10 @@ type TokenPoolInterface interface { GetToken(opts *bind.CallOpts) (common.Address, error) + GetTokenDecimals(opts *bind.CallOpts) (uint8, error) + + IsRemotePool(opts *bind.CallOpts, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) @@ -2661,20 +2853,22 @@ type TokenPoolInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + AddRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) - ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + ApplyChainUpdates(opts *bind.TransactOpts, remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + RemoveRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) - SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) - SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) @@ -2757,11 +2951,17 @@ type TokenPoolInterface interface { ParseReleased(log types.Log) (*TokenPoolReleased, error) - FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*TokenPoolRemotePoolSetIterator, error) + FilterRemotePoolAdded(opts *bind.FilterOpts, remoteChainSelector []uint64) (*TokenPoolRemotePoolAddedIterator, error) + + WatchRemotePoolAdded(opts *bind.WatchOpts, sink chan<- *TokenPoolRemotePoolAdded, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolAdded(log types.Log) (*TokenPoolRemotePoolAdded, error) + + FilterRemotePoolRemoved(opts *bind.FilterOpts, remoteChainSelector []uint64) (*TokenPoolRemotePoolRemovedIterator, error) - WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *TokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + WatchRemotePoolRemoved(opts *bind.WatchOpts, sink chan<- *TokenPoolRemotePoolRemoved, remoteChainSelector []uint64) (event.Subscription, error) - ParseRemotePoolSet(log types.Log) (*TokenPoolRemotePoolSet, error) + ParseRemotePoolRemoved(log types.Log) (*TokenPoolRemotePoolRemoved, error) FilterRouterUpdated(opts *bind.FilterOpts) (*TokenPoolRouterUpdatedIterator, error) diff --git a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go index 1d6b173b628..0462cd036ba 100644 --- a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go +++ b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go @@ -74,8 +74,7 @@ type RateLimiterTokenBucket struct { type TokenPoolChainUpdate struct { RemoteChainSelector uint64 - Allowed bool - RemotePoolAddress []byte + RemotePoolAddresses [][]byte RemoteTokenAddress []byte OutboundRateLimiterConfig RateLimiterConfig InboundRateLimiterConfig RateLimiterConfig @@ -95,8 +94,8 @@ type USDCTokenPoolDomainUpdate struct { } var USDCTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"previousPoolAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chains\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePool\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"setRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101406040523480156200001257600080fd5b506040516200520538038062005205833981016040819052620000359162000ae9565b83838383336000816200005b57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03848116919091179091558116156200008e576200008e81620003e9565b50506001600160a01b0384161580620000ae57506001600160a01b038116155b80620000c157506001600160a01b038216155b15620000e0576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0384811660805282811660a052600480546001600160a01b031916918316919091179055825115801560c052620001335760408051600081526020810190915262000133908462000463565b5050506001600160a01b038616905062000160576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001c7919062000c0f565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200020a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000230919062000c36565b905063ffffffff81161562000265576040516334697c6b60e11b815263ffffffff821660048201526024015b60405180910390fd5b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002a6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002cc919062000c36565b905063ffffffff811615620002fd576040516316ba39c560e31b815263ffffffff821660048201526024016200025c565b6001600160a01b0380891660e05283166101008190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa1580156200034f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000375919062000c36565b63ffffffff166101205260e0516080516200039f916001600160a01b0390911690600019620005c0565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000d83565b336001600160a01b038216036200041357604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000484576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200050f576000838281518110620004a857620004a862000c5e565b60209081029190910101519050620004c2600282620006a6565b1562000505576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000487565b5060005b8151811015620005bb57600082828151811062000534576200053462000c5e565b6020026020010151905060006001600160a01b0316816001600160a01b031603620005605750620005b2565b6200056d600282620006c6565b15620005b0576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000513565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000612573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000638919062000c74565b62000644919062000ca4565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152919250620006a091869190620006dd16565b50505050565b6000620006bd836001600160a01b038416620007ae565b90505b92915050565b6000620006bd836001600160a01b038416620008b2565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906200072c906001600160a01b03851690849062000904565b805190915015620005bb57808060200190518101906200074d919062000cba565b620005bb5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016200025c565b60008181526001830160205260408120548015620008a7576000620007d560018362000cde565b8554909150600090620007eb9060019062000cde565b9050808214620008575760008660000182815481106200080f576200080f62000c5e565b906000526020600020015490508087600001848154811062000835576200083562000c5e565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200086b576200086b62000cf4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620006c0565b6000915050620006c0565b6000818152600183016020526040812054620008fb57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620006c0565b506000620006c0565b60606200091584846000856200091d565b949350505050565b606082471015620009805760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016200025c565b600080866001600160a01b031685876040516200099e919062000d30565b60006040518083038185875af1925050503d8060008114620009dd576040519150601f19603f3d011682016040523d82523d6000602084013e620009e2565b606091505b509092509050620009f68783838762000a01565b979650505050505050565b6060831562000a7557825160000362000a6d576001600160a01b0385163b62000a6d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016200025c565b508162000915565b62000915838381511562000a8c5781518083602001fd5b8060405162461bcd60e51b81526004016200025c919062000d4e565b6001600160a01b038116811462000abe57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000ae48162000aa8565b919050565b600080600080600060a0868803121562000b0257600080fd5b855162000b0f8162000aa8565b8095505060208087015162000b248162000aa8565b60408801519095506001600160401b038082111562000b4257600080fd5b818901915089601f83011262000b5757600080fd5b81518181111562000b6c5762000b6c62000ac1565b8060051b604051601f19603f8301168101818110858211171562000b945762000b9462000ac1565b60405291825284820192508381018501918c83111562000bb357600080fd5b938501935b8285101562000bdc5762000bcc8562000ad7565b8452938501939285019262000bb8565b80985050505050505062000bf36060870162000ad7565b915062000c036080870162000ad7565b90509295509295909350565b60006020828403121562000c2257600080fd5b815162000c2f8162000aa8565b9392505050565b60006020828403121562000c4957600080fd5b815163ffffffff8116811462000c2f57600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000c8757600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620006c057620006c062000c8e565b60006020828403121562000ccd57600080fd5b8151801515811462000c2f57600080fd5b81810381811115620006c057620006c062000c8e565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d2757818101518382015260200162000d0d565b50506000910152565b6000825162000d4481846020870162000d0a565b9190910192915050565b602081526000825180602084015262000d6f81604085016020870162000d0a565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516143c962000e3c60003960008181610382015281816111d401528181611e1d0152611e7b0152600081816106760152610a7801526000818161035b01526110ea01526000818161063a01528181611f18015261282201526000818161057601528181611c1b01526121ce01526000818161028f015281816102e4015281816110b401528181611b3b015281816120ee015281816127b80152612a0d01526143c96000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80639a4575b91161010f578063c75eea9c116100a2578063dfadfa3511610071578063dfadfa351461059a578063e0351e1314610638578063f2fde38b1461065e578063fbf84dd71461067157600080fd5b8063c75eea9c1461053b578063cf7401f31461054e578063db6327dc14610561578063dc0bd9711461057457600080fd5b8063b0f479a1116100de578063b0f479a1146104e2578063b794658014610500578063c0d7865514610513578063c4bffe2b1461052657600080fd5b80639a4575b9146104365780639fdf13ff14610456578063a7cd63b71461045e578063af58d59f1461047357600080fd5b80636155cda01161018757806379ba50971161015657806379ba5097146103ea5780637d54534e146103f25780638926f54f146104055780638da5cb5b1461041857600080fd5b80636155cda0146103565780636b716b0d1461037d5780636d3d1a58146103b957806378a010b2146103d757600080fd5b806321df0da7116101c357806321df0da71461028d578063240028e8146102d4578063390775371461032157806354c8a4f31461034357600080fd5b806241d3c1146101f457806301ffc9a7146102095780630a2fd49314610231578063181f5a7714610251575b600080fd5b6102076102023660046131b0565b610698565b005b61021c610217366004613225565b610835565b60405190151581526020015b60405180910390f35b61024461023f36600461328d565b61091a565b604051610228919061330e565b6102446040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e352e300000000000000000000000000081525081565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610228565b61021c6102e236600461334e565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b61033461032f36600461336b565b6109ca565b60405190518152602001610228565b6102076103513660046133f3565b610bb7565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6103a47f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610228565b60085473ffffffffffffffffffffffffffffffffffffffff166102af565b6102076103e536600461345f565b610c32565b610207610da1565b61020761040036600461334e565b610e6f565b61021c61041336600461328d565b610ef0565b60015473ffffffffffffffffffffffffffffffffffffffff166102af565b6104496104443660046134e4565b610f07565b604051610228919061351f565b6103a4600081565b61046661124f565b604051610228919061357f565b61048661048136600461328d565b611260565b604051610228919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102af565b61024461050e36600461328d565b611335565b61020761052136600461334e565b611360565b61052e611434565b60405161022891906135d9565b61048661054936600461328d565b6114ec565b61020761055c366004613764565b6115be565b61020761056f3660046137ab565b611647565b7f00000000000000000000000000000000000000000000000000000000000000006102af565b61060e6105a836600461328d565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600982529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610228565b7f000000000000000000000000000000000000000000000000000000000000000061021c565b61020761066c36600461334e565b611acd565b6102af7f000000000000000000000000000000000000000000000000000000000000000081565b6106a0611ae1565b60005b818110156107f75760008383838181106106bf576106bf6137ed565b9050608002018036038101906106d59190613830565b805190915015806106f25750604081015167ffffffffffffffff16155b1561076157604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600990925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169190931617929092179055016106a3565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee5682826040516108299291906138aa565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf0000000000000000000000000000000000000000000000000000000014806108c857507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b8061091457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061094590613931565b80601f016020809104026020016040519081016040528092919081815260200182805461097190613931565b80156109be5780601f10610993576101008083540402835291602001916109be565b820191906000526020600020905b8154815290600101906020018083116109a157829003601f168201915b50505050509050919050565b6040805160208101909152600081526109ea6109e583613a2f565b611b34565b60006109f960c0840184613b24565b810190610a069190613b89565b90506000610a1760e0850185613b24565b810190610a249190613bc8565b9050610a34816000015183611d65565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aab92600401613c59565b6020604051808303816000875af1158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190613c7e565b610b24576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b34606085016040860161334e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610b9691815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b610bbf611ae1565b610c2c84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250611f1692505050565b50505050565b610c3a611ae1565b610c4383610ef0565b610c85576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b67ffffffffffffffff831660009081526007602052604081206004018054610cac90613931565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd890613931565b8015610d255780601f10610cfa57610100808354040283529160200191610d25565b820191906000526020600020905b815481529060010190602001808311610d0857829003601f168201915b5050505067ffffffffffffffff8616600090815260076020526040902091925050600401610d54838583613ce3565b508367ffffffffffffffff167fdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf828585604051610d9393929190613e47565b60405180910390a250505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610df2576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e77611ae1565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b6000610914600567ffffffffffffffff84166120cc565b6040805180820190915260608082526020820152610f2c610f2783613e77565b6120e7565b6000600981610f41604086016020870161328d565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff161515908201819052909150610fe857610fa9604084016020850161328d565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b610ff28380613b24565b9050602014611039576110058380613b24565b6040517fa3c8cf09000000000000000000000000000000000000000000000000000000008152600401610758929190613f1b565b60006110458480613b24565b8101906110529190613f2f565b602083015183516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060880135600482015263ffffffff90921660248301526044820183905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063f856ddb69060a4016020604051808303816000875af1158015611133573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111579190613f48565b6040516060870135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260405180604001604052806111b487602001602081019061050e919061328d565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905295945050505050565b606061125b60026122b1565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526003909101548084166060830152919091049091166080820152610914906122be565b67ffffffffffffffff8116600090815260076020526040902060050180546060919061094590613931565b611368611ae1565b73ffffffffffffffffffffffffffffffffffffffff81166113b5576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f16849101610829565b6060600061144260056122b1565b90506000815167ffffffffffffffff8111156114605761146061361b565b604051908082528060200260200182016040528015611489578160200160208202803683370190505b50905060005b82518110156114e5578281815181106114aa576114aa6137ed565b60200260200101518282815181106114c4576114c46137ed565b67ffffffffffffffff9092166020928302919091019091015260010161148f565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff161515948201949094526001909101548084166060830152919091049091166080820152610914906122be565b60085473ffffffffffffffffffffffffffffffffffffffff1633148015906115fe575060015473ffffffffffffffffffffffffffffffffffffffff163314155b15611637576040517f8e4a23d6000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b611642838383612370565b505050565b61164f611ae1565b60005b8181101561164257600083838381811061166e5761166e6137ed565b90506020028101906116809190613f65565b61168990613fa3565b905061169e816080015182602001511561245a565b6116b18160a0015182602001511561245a565b8060200151156119ad5780516116d39060059067ffffffffffffffff16612593565b6117185780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b604081015151158061172d5750606081015151155b15611764576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805161012081018252608083810180516020908101516fffffffffffffffffffffffffffffffff9081168486019081524263ffffffff90811660a0808901829052865151151560c08a01528651860151851660e08a015295518901518416610100890152918752875180860189529489018051850151841686528585019290925281515115158589015281518401518316606080870191909152915188015183168587015283870194855288880151878901908152828a015183890152895167ffffffffffffffff1660009081526007865289902088518051825482890151838e01519289167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316177001000000000000000000000000000000009188168202177fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff90811674010000000000000000000000000000000000000000941515850217865584890151948d0151948a16948a168202949094176001860155995180516002860180549b8301519f830151918b169b9093169a909a179d9096168a029c909c179091169615150295909517909855908101519401519381169316909102919091176003820155915190919060048201906119459082614057565b506060820151600582019061195a9082614057565b505081516060830151608084015160a08501516040517f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c295506119a09493929190614171565b60405180910390a1611ac4565b80516119c59060059067ffffffffffffffff1661259f565b611a0a5780516040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152602401610758565b805167ffffffffffffffff16600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611a736004830182613162565b611a81600583016000613162565b5050805160405167ffffffffffffffff90911681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599169060200160405180910390a15b50600101611652565b611ad5611ae1565b611ade816125ab565b50565b60015473ffffffffffffffffffffffffffffffffffffffff163314611b32576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff908116911614611bc95760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa158015611c77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9b9190613c7e565b15611cd2576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cdf816020015161266f565b6000611cee826020015161091a565b9050805160001480611d12575080805190602001208260a001518051906020012014155b15611d4f578160a001516040517f24eb47e5000000000000000000000000000000000000000000000000000000008152600401610758919061330e565b611d6182602001518360600151612795565b5050565b600482015163ffffffff811615611db0576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff82166004820152602401610758565b6008830151600c8401516014850151602085015163ffffffff808516911614611e1b5760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff91821660048201529084166024820152604401610758565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611eb0576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015283166024820152604401610758565b845167ffffffffffffffff828116911614611f0e5784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff91821660048201529082166024820152604401610758565b505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000611f6d576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015612003576000838281518110611f8d57611f8d6137ed565b60200260200101519050611fab8160026127dc90919063ffffffff16565b15611ffa5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101611f70565b5060005b8151811015611642576000828281518110612024576120246137ed565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361206857506120c4565b6120736002826127fe565b156120c25760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b600101612007565b600081815260018301602052604081205415155b9392505050565b60808101517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161461217c5760808101516040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610758565b60208101516040517f2cbc26bb00000000000000000000000000000000000000000000000000000000815260809190911b77ffffffffffffffff000000000000000000000000000000001660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632cbc26bb90602401602060405180830381865afa15801561222a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224e9190613c7e565b15612285576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6122928160400151612820565b61229f816020015161289f565b611ade816020015182606001516129ed565b606060006120e083612a31565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261234c82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426123309190614239565b85608001516fffffffffffffffffffffffffffffffff16612a8c565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61237983610ef0565b6123bb576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152602401610758565b6123c682600061245a565b67ffffffffffffffff831660009081526007602052604090206123e99083612ab6565b6123f481600061245a565b67ffffffffffffffff8316600090815260076020526040902061241a9060020182612ab6565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b83838360405161244d9392919061424c565b60405180910390a1505050565b8151156125215781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff161015806124b0575060408201516fffffffffffffffffffffffffffffffff16155b156124e957816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161075891906142cf565b8015611d61576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408201516fffffffffffffffffffffffffffffffff1615158061255a575060208201516fffffffffffffffffffffffffffffffff1615155b15611d6157816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161075891906142cf565b60006120e08383612c58565b60006120e08383612ca7565b3373ffffffffffffffffffffffffffffffffffffffff8216036125fa576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b61267881610ef0565b6126ba576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612739573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061275d9190613c7e565b611ade576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d6190600201827f0000000000000000000000000000000000000000000000000000000000000000612d9a565b60006120e08373ffffffffffffffffffffffffffffffffffffffff8416612ca7565b60006120e08373ffffffffffffffffffffffffffffffffffffffff8416612c58565b7f000000000000000000000000000000000000000000000000000000000000000015611ade5761285160028261311d565b611ade576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610758565b6128a881610ef0565b6128ea576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff82166004820152602401610758565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612963573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612987919061430b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611ade576040517f728fe07b000000000000000000000000000000000000000000000000000000008152336004820152602401610758565b67ffffffffffffffff82166000908152600760205260409020611d6190827f0000000000000000000000000000000000000000000000000000000000000000612d9a565b6060816000018054806020026020016040519081016040528092919081815260200182805480156109be57602002820191906000526020600020905b815481526020019060010190808311612a6d5750505050509050919050565b6000612aab85612a9c8486614328565b612aa6908761433f565b61314c565b90505b949350505050565b8154600090612adf90700100000000000000000000000000000000900463ffffffff1642614239565b90508015612b815760018301548354612b27916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612a8c565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612ba7916fffffffffffffffffffffffffffffffff908116911661314c565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061244d9084906142cf565b6000818152600183016020526040812054612c9f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610914565b506000610914565b60008181526001830160205260408120548015612d90576000612ccb600183614239565b8554909150600090612cdf90600190614239565b9050808214612d44576000866000018281548110612cff57612cff6137ed565b9060005260206000200154905080876000018481548110612d2257612d226137ed565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612d5557612d55614352565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610914565b6000915050610914565b825474010000000000000000000000000000000000000000900460ff161580612dc1575081155b15612dcb57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090612e1190700100000000000000000000000000000000900463ffffffff1642614239565b90508015612ed15781831115612e53576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154612e8d9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612a8c565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015612f885773ffffffffffffffffffffffffffffffffffffffff8416612f30576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610758565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610758565b8483101561309b5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290612fcc9082614239565b612fd6878a614239565b612fe0919061433f565b612fea9190614381565b905073ffffffffffffffffffffffffffffffffffffffff8616613043576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610758565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610758565b6130a58584614239565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156120e0565b600081831061315b57816120e0565b5090919050565b50805461316e90613931565b6000825580601f1061317e575050565b601f016020900490600052602060002090810190611ade91905b808211156131ac5760008155600101613198565b5090565b600080602083850312156131c357600080fd5b823567ffffffffffffffff808211156131db57600080fd5b818501915085601f8301126131ef57600080fd5b8135818111156131fe57600080fd5b8660208260071b850101111561321357600080fd5b60209290920196919550909350505050565b60006020828403121561323757600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146120e057600080fd5b67ffffffffffffffff81168114611ade57600080fd5b803561328881613267565b919050565b60006020828403121561329f57600080fd5b81356120e081613267565b6000815180845260005b818110156132d0576020818501810151868301820152016132b4565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006120e060208301846132aa565b73ffffffffffffffffffffffffffffffffffffffff81168114611ade57600080fd5b803561328881613321565b60006020828403121561336057600080fd5b81356120e081613321565b60006020828403121561337d57600080fd5b813567ffffffffffffffff81111561339457600080fd5b820161010081850312156120e057600080fd5b60008083601f8401126133b957600080fd5b50813567ffffffffffffffff8111156133d157600080fd5b6020830191508360208260051b85010111156133ec57600080fd5b9250929050565b6000806000806040858703121561340957600080fd5b843567ffffffffffffffff8082111561342157600080fd5b61342d888389016133a7565b9096509450602087013591508082111561344657600080fd5b50613453878288016133a7565b95989497509550505050565b60008060006040848603121561347457600080fd5b833561347f81613267565b9250602084013567ffffffffffffffff8082111561349c57600080fd5b818601915086601f8301126134b057600080fd5b8135818111156134bf57600080fd5b8760208285010111156134d157600080fd5b6020830194508093505050509250925092565b6000602082840312156134f657600080fd5b813567ffffffffffffffff81111561350d57600080fd5b820160a081850312156120e057600080fd5b60208152600082516040602084015261353b60608401826132aa565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261357682826132aa565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156135cd57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161359b565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156135cd57835167ffffffffffffffff16835292840192918401916001016135f5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff8111828210171561366e5761366e61361b565b60405290565b6040805190810167ffffffffffffffff8111828210171561366e5761366e61361b565b60405160c0810167ffffffffffffffff8111828210171561366e5761366e61361b565b8015158114611ade57600080fd5b8035613288816136ba565b80356fffffffffffffffffffffffffffffffff8116811461328857600080fd5b60006060828403121561370557600080fd5b6040516060810181811067ffffffffffffffff821117156137285761372861361b565b6040529050808235613739816136ba565b8152613747602084016136d3565b6020820152613758604084016136d3565b60408201525092915050565b600080600060e0848603121561377957600080fd5b833561378481613267565b925061379385602086016136f3565b91506137a285608086016136f3565b90509250925092565b600080602083850312156137be57600080fd5b823567ffffffffffffffff8111156137d557600080fd5b6137e1858286016133a7565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff8116811461328857600080fd5b60006080828403121561384257600080fd5b6040516080810181811067ffffffffffffffff821117156138655761386561361b565b604052823581526138786020840161381c565b6020820152604083013561388b81613267565b6040820152606083013561389e816136ba565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613924578135835263ffffffff6138dc86840161381c565b1685840152838201356138ee81613267565b67ffffffffffffffff168385015260608281013561390b816136ba565b15159084015260809283019291909101906001016138c0565b5090979650505050505050565b600181811c9082168061394557607f821691505b60208210810361397e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f83011261399557600080fd5b813567ffffffffffffffff808211156139b0576139b061361b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156139f6576139f661361b565b81604052838152866020858801011115613a0f57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101008236031215613a4257600080fd5b613a4a61364a565b823567ffffffffffffffff80821115613a6257600080fd5b613a6e36838701613984565b8352613a7c6020860161327d565b6020840152613a8d60408601613343565b604084015260608501356060840152613aa860808601613343565b608084015260a0850135915080821115613ac157600080fd5b613acd36838701613984565b60a084015260c0850135915080821115613ae657600080fd5b613af236838701613984565b60c084015260e0850135915080821115613b0b57600080fd5b50613b1836828601613984565b60e08301525092915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613b5957600080fd5b83018035915067ffffffffffffffff821115613b7457600080fd5b6020019150368190038213156133ec57600080fd5b600060408284031215613b9b57600080fd5b613ba3613674565b8235613bae81613267565b8152613bbc6020840161381c565b60208201529392505050565b600060208284031215613bda57600080fd5b813567ffffffffffffffff80821115613bf257600080fd5b9083019060408286031215613c0657600080fd5b613c0e613674565b823582811115613c1d57600080fd5b613c2987828601613984565b825250602083013582811115613c3e57600080fd5b613c4a87828601613984565b60208301525095945050505050565b604081526000613c6c60408301856132aa565b828103602084015261357681856132aa565b600060208284031215613c9057600080fd5b81516120e0816136ba565b601f821115611642576000816000526020600020601f850160051c81016020861015613cc45750805b601f850160051c820191505b81811015611f0e57828155600101613cd0565b67ffffffffffffffff831115613cfb57613cfb61361b565b613d0f83613d098354613931565b83613c9b565b6000601f841160018114613d615760008515613d2b5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355613df7565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015613db05786850135825560209485019460019092019101613d90565b5086821015613deb577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000613e5a60408301866132aa565b8281036020840152613e6d818587613dfe565b9695505050505050565b600060a08236031215613e8957600080fd5b60405160a0810167ffffffffffffffff8282108183111715613ead57613ead61361b565b816040528435915080821115613ec257600080fd5b50613ecf36828601613984565b8252506020830135613ee081613267565b60208201526040830135613ef381613321565b6040820152606083810135908201526080830135613f1081613321565b608082015292915050565b602081526000612aae602083018486613dfe565b600060208284031215613f4157600080fd5b5035919050565b600060208284031215613f5a57600080fd5b81516120e081613267565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec1833603018112613f9957600080fd5b9190910192915050565b60006101408236031215613fb657600080fd5b613fbe613697565b613fc78361327d565b8152613fd5602084016136c8565b6020820152604083013567ffffffffffffffff80821115613ff557600080fd5b61400136838701613984565b6040840152606085013591508082111561401a57600080fd5b5061402736828601613984565b60608301525061403a36608085016136f3565b608082015261404c3660e085016136f3565b60a082015292915050565b815167ffffffffffffffff8111156140715761407161361b565b6140858161407f8454613931565b84613c9b565b602080601f8311600181146140d857600084156140a25750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611f0e565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561412557888601518255948401946001909101908401614106565b508582101561416157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff87168352806020840152614195818401876132aa565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506141d39050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152613576565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109145761091461420a565b67ffffffffffffffff8416815260e0810161429860208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152612aae565b6060810161091482848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561431d57600080fd5b81516120e081613321565b80820281158282048414176109145761091461420a565b808201808211156109145761091461420a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826143b7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotARampOnRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CursedByRMN\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"DisabledNonZeroRateLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"InvalidRateLimitRate\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"}],\"name\":\"InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"}],\"name\":\"InvalidRemoteChainDecimals\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidRemotePoolForChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidSourcePoolAddress\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"NonExistentChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RateLimitMustBeDisabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remoteToken\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"ChainConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"ChainRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"RateLimitAdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"RemotePoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldRouter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"RouterUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"TokensConsumed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"addRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64[]\",\"name\":\"remoteChainSelectorsToRemove\",\"type\":\"uint64[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"remotePoolAddresses\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"remoteTokenAddress\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundRateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundRateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.ChainUpdate[]\",\"name\":\"chainsToAdd\",\"type\":\"tuple[]\"}],\"name\":\"applyChainUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentInboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getCurrentOutboundRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRateLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemotePools\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"getRemoteToken\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRmnProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"rmnProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRouter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedChains\",\"outputs\":[{\"internalType\":\"uint64[]\",\"name\":\"\",\"type\":\"uint64[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"decimals\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_messageTransmitter\",\"outputs\":[{\"internalType\":\"contractIMessageTransmitter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_tokenMessenger\",\"outputs\":[{\"internalType\":\"contractITokenMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"isRemotePool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"}],\"name\":\"isSupportedChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"isSupportedToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"}],\"internalType\":\"structPool.LockOrBurnInV1\",\"name\":\"lockOrBurnIn\",\"type\":\"tuple\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"destTokenAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destPoolData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.LockOrBurnOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"localToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"sourcePoolData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"offchainTokenData\",\"type\":\"bytes\"}],\"internalType\":\"structPool.ReleaseOrMintInV1\",\"name\":\"releaseOrMintIn\",\"type\":\"tuple\"}],\"name\":\"releaseOrMint\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"destinationAmount\",\"type\":\"uint256\"}],\"internalType\":\"structPool.ReleaseOrMintOutV1\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"remotePoolAddress\",\"type\":\"bytes\"}],\"name\":\"removeRemotePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"outboundConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"inboundConfig\",\"type\":\"tuple\"}],\"name\":\"setChainRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rateLimitAdmin\",\"type\":\"address\"}],\"name\":\"setRateLimitAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRouter\",\"type\":\"address\"}],\"name\":\"setRouter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101606040523480156200001257600080fd5b50604051620053f5380380620053f5833981016040819052620000359162000af6565b836006848484336000816200005d57604051639b15e16f60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b038481169190911790915581161562000090576200009081620003f6565b50506001600160a01b0385161580620000b057506001600160a01b038116155b80620000c357506001600160a01b038216155b15620000e2576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b0385811660805282811660c05260ff851660a052600480546001600160a01b031916918316919091179055825115801560e0526200013c576040805160008152602081019091526200013c908462000470565b5050506001600160a01b03871691506200016b9050576040516306b7c75960e31b815260040160405180910390fd5b6000856001600160a01b0316632c1219216040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001ac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001d2919062000c1c565b90506000816001600160a01b03166354fd4d506040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000215573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200023b919062000c43565b905063ffffffff81161562000270576040516334697c6b60e11b815263ffffffff821660048201526024015b60405180910390fd5b6000876001600160a01b0316639cdbb1816040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002b1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002d7919062000c43565b905063ffffffff81161562000308576040516316ba39c560e31b815263ffffffff8216600482015260240162000267565b6001600160a01b038089166101005283166101208190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa1580156200035b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000381919062000c43565b63ffffffff166101405261010051608051620003ac916001600160a01b0390911690600019620005cd565b6040516001600160a01b03891681527f2e902d38f15b233cbb63711add0fca4545334d3a169d60c0a616494d7eea95449060200160405180910390a1505050505050505062000d90565b336001600160a01b038216036200042057604051636d6c4ee560e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b03838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e05162000491576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200051c576000838281518110620004b557620004b562000c6b565b60209081029190910101519050620004cf600282620006b3565b1562000512576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5060010162000494565b5060005b8151811015620005c857600082828151811062000541576200054162000c6b565b6020026020010151905060006001600160a01b0316816001600160a01b0316036200056d5750620005bf565b6200057a600282620006d3565b15620005bd576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010162000520565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa1580156200061f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000645919062000c81565b62000651919062000cb1565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152919250620006ad91869190620006ea16565b50505050565b6000620006ca836001600160a01b038416620007bb565b90505b92915050565b6000620006ca836001600160a01b038416620008bf565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65649082015260009062000739906001600160a01b03851690849062000911565b805190915015620005c857808060200190518101906200075a919062000cc7565b620005c85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000267565b60008181526001830160205260408120548015620008b4576000620007e260018362000ceb565b8554909150600090620007f89060019062000ceb565b9050808214620008645760008660000182815481106200081c576200081c62000c6b565b906000526020600020015490508087600001848154811062000842576200084262000c6b565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000878576200087862000d01565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620006cd565b6000915050620006cd565b60008181526001830160205260408120546200090857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620006cd565b506000620006cd565b60606200092284846000856200092a565b949350505050565b6060824710156200098d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000267565b600080866001600160a01b03168587604051620009ab919062000d3d565b60006040518083038185875af1925050503d8060008114620009ea576040519150601f19603f3d011682016040523d82523d6000602084013e620009ef565b606091505b50909250905062000a038783838762000a0e565b979650505050505050565b6060831562000a8257825160000362000a7a576001600160a01b0385163b62000a7a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000267565b508162000922565b62000922838381511562000a995781518083602001fd5b8060405162461bcd60e51b815260040162000267919062000d5b565b6001600160a01b038116811462000acb57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b805162000af18162000ab5565b919050565b600080600080600060a0868803121562000b0f57600080fd5b855162000b1c8162000ab5565b8095505060208087015162000b318162000ab5565b60408801519095506001600160401b038082111562000b4f57600080fd5b818901915089601f83011262000b6457600080fd5b81518181111562000b795762000b7962000ace565b8060051b604051601f19603f8301168101818110858211171562000ba15762000ba162000ace565b60405291825284820192508381018501918c83111562000bc057600080fd5b938501935b8285101562000be95762000bd98562000ae4565b8452938501939285019262000bc5565b80985050505050505062000c006060870162000ae4565b915062000c106080870162000ae4565b90509295509295909350565b60006020828403121562000c2f57600080fd5b815162000c3c8162000ab5565b9392505050565b60006020828403121562000c5657600080fd5b815163ffffffff8116811462000c3c57600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000c9457600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115620006cd57620006cd62000c9b565b60006020828403121562000cda57600080fd5b8151801515811462000c3c57600080fd5b81810381811115620006cd57620006cd62000c9b565b634e487b7160e01b600052603160045260246000fd5b60005b8381101562000d3457818101518382015260200162000d1a565b50506000910152565b6000825162000d5181846020870162000d17565b9190910192915050565b602081526000825180602084015262000d7c81604085016020870162000d17565b601f01601f19169190910160400192915050565b60805160a05160c05160e0516101005161012051610140516145af62000e46600039600081816104170152818161113c01528181612107015261216501526000818161072b0152610a750152600081816103dd01526110520152600081816106dc0152818161221d0152612bcc01526000818161061801528181611eb40152612509015260006103660152600081816102cd015281816103220152818161101c01528181612b620152612db701526145af6000f3fe608060405234801561001057600080fd5b50600436106102405760003560e01c80639a4575b911610145578063c4bffe2b116100bd578063dfadfa351161008c578063e8a1da1711610071578063e8a1da1714610700578063f2fde38b14610713578063fbf84dd71461072657600080fd5b8063dfadfa351461063c578063e0351e13146106da57600080fd5b8063c4bffe2b146105db578063c75eea9c146105f0578063cf7401f314610603578063dc0bd9711461061657600080fd5b8063acfecf9111610114578063b0f479a1116100f9578063b0f479a114610597578063b7946580146105b5578063c0d78655146105c857600080fd5b8063acfecf9114610515578063af58d59f1461052857600080fd5b80639a4575b9146104b85780639fdf13ff146104d8578063a42a7b8b146104e0578063a7cd63b71461050057600080fd5b806354c8a4f3116101d85780636d3d1a58116101a75780637d54534e1161018c5780637d54534e146104745780638926f54f146104875780638da5cb5b1461049a57600080fd5b80636d3d1a581461044e57806379ba50971461046c57600080fd5b806354c8a4f3146103c55780636155cda0146103d857806362ddd3c4146103ff5780636b716b0d1461041257600080fd5b8063240028e811610214578063240028e81461031257806324f65ee71461035f57806339077537146103905780634c5ef0ed146103b257600080fd5b806241d3c11461024557806301ffc9a71461025a578063181f5a771461028257806321df0da7146102cb575b600080fd5b610258610253366004613577565b61074d565b005b61026d6102683660046135ec565b6108ea565b60405190151581526020015b60405180910390f35b6102be6040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e352e310000000000000000000000000081525081565b6040516102799190613692565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610279565b61026d6103203660046136c7565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610279565b6103a361039e3660046136e4565b6109cf565b60405190518152602001610279565b61026d6103c0366004613736565b610bb4565b6102586103d3366004613807565b610bfe565b6102ed7f000000000000000000000000000000000000000000000000000000000000000081565b61025861040d366004613736565b610c79565b6104397f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610279565b60095473ffffffffffffffffffffffffffffffffffffffff166102ed565b610258610d11565b6102586104823660046136c7565b610ddf565b61026d610495366004613873565b610e60565b60015473ffffffffffffffffffffffffffffffffffffffff166102ed565b6104cb6104c6366004613890565b610e77565b60405161027991906138cb565b610439600081565b6104f36104ee366004613873565b6111b7565b6040516102799190613922565b610508611322565b60405161027991906139a4565b610258610523366004613736565b611333565b61053b610536366004613873565b61144b565b604051610279919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60045473ffffffffffffffffffffffffffffffffffffffff166102ed565b6102be6105c3366004613873565b611520565b6102586105d63660046136c7565b6115d0565b6105e36116a4565b60405161027991906139fe565b61053b6105fe366004613873565b61175c565b610258610611366004613b8b565b61182e565b7f00000000000000000000000000000000000000000000000000000000000000006102ed565b6106b061064a366004613873565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600a82529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff169082015291810151151590820152606001610279565b7f000000000000000000000000000000000000000000000000000000000000000061026d565b61025861070e366004613807565b6118b2565b6102586107213660046136c7565b611dc4565b6102ed7f000000000000000000000000000000000000000000000000000000000000000081565b610755611dd8565b60005b818110156108ac57600083838381811061077457610774613bd2565b90506080020180360381019061078a9190613c15565b805190915015806107a75750604081015167ffffffffffffffff16155b1561081657604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600a90925293902091518255516001918201805494511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909516919093161792909217905501610758565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee5682826040516108de929190613c8f565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167faff2afbf00000000000000000000000000000000000000000000000000000000148061097d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e64dd2900000000000000000000000000000000000000000000000000000000145b806109c957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6040805160208101909152600081526109e782611e2b565b60006109f660c0840184613d16565b810190610a039190613d7b565b90506000610a1460e0850185613d16565b810190610a219190613e48565b9050610a3181600001518361204f565b805160208201516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016926357ecfd2892610aa892600401613ed9565b6020604051808303816000875af1158015610ac7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aeb9190613efe565b610b21576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3160608501604086016136c7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f08660600135604051610b9391815260200190565b60405180910390a35050604080516020810190915260609092013582525090565b6000610bf68383604051610bc9929190613f1b565b604080519182900390912067ffffffffffffffff8716600090815260076020529190912060050190612200565b949350505050565b610c06611dd8565b610c738484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061221b92505050565b50505050565b610c81611dd8565b610c8a83610e60565b610ccc576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080d565b610d0c8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506123d192505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d62576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560008054909116815560405173ffffffffffffffffffffffffffffffffffffffff909216929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610de7611dd8565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f44676b5284b809a22248eba0da87391d79098be38bb03154be88a58bf4d091749060200160405180910390a150565b60006109c9600567ffffffffffffffff8416612200565b6040805180820190915260608082526020820152610e94826124cb565b6000600a81610ea96040860160208701613873565b67ffffffffffffffff168152602080820192909252604090810160002081516060810183528154815260019091015463ffffffff81169382019390935264010000000090920460ff161515908201819052909150610f5057610f116040840160208501613873565b6040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161080d565b610f5a8380613d16565b9050602014610fa157610f6d8380613d16565b6040517fa3c8cf0900000000000000000000000000000000000000000000000000000000815260040161080d929190613f74565b6000610fad8480613d16565b810190610fba9190613f88565b602083015183516040517ff856ddb60000000000000000000000000000000000000000000000000000000081526060880135600482015263ffffffff90921660248301526044820183905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529192506000917f0000000000000000000000000000000000000000000000000000000000000000169063f856ddb69060a4016020604051808303816000875af115801561109b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110bf9190613fa1565b6040516060870135815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a2604051806040016040528061111c8760200160208101906105c39190613873565b815260408051808201825267ffffffffffffffff851680825263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602093840190815284518085019390935251169281019290925290910190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905295945050505050565b67ffffffffffffffff81166000908152600760205260408120606091906111e090600501612657565b90506000815167ffffffffffffffff8111156111fe576111fe613a40565b60405190808252806020026020018201604052801561123157816020015b606081526020019060019003908161121c5790505b50905060005b825181101561131a576008600084838151811061125657611256613bd2565b60200260200101518152602001908152602001600020805461127790613fbe565b80601f01602080910402602001604051908101604052809291908181526020018280546112a390613fbe565b80156112f05780601f106112c5576101008083540402835291602001916112f0565b820191906000526020600020905b8154815290600101906020018083116112d357829003601f168201915b505050505082828151811061130757611307613bd2565b6020908102919091010152600101611237565b509392505050565b606061132e6002612657565b905090565b61133b611dd8565b61134483610e60565b611386576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080d565b6113c68282604051611399929190613f1b565b604080519182900390912067ffffffffffffffff8616600090815260076020529190912060050190612664565b611402578282826040517f74f23c7c00000000000000000000000000000000000000000000000000000000815260040161080d93929190614011565b8267ffffffffffffffff167f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d76838360405161143e929190613f74565b60405180910390a2505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845260028201546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260039091015480841660608301529190910490911660808201526109c990612670565b67ffffffffffffffff8116600090815260076020526040902060040180546060919061154b90613fbe565b80601f016020809104026020016040519081016040528092919081815260200182805461157790613fbe565b80156115c45780601f10611599576101008083540402835291602001916115c4565b820191906000526020600020905b8154815290600101906020018083116115a757829003601f168201915b50505050509050919050565b6115d8611dd8565b73ffffffffffffffffffffffffffffffffffffffff8116611625576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f168491016108de565b606060006116b26005612657565b90506000815167ffffffffffffffff8111156116d0576116d0613a40565b6040519080825280602002602001820160405280156116f9578160200160208202803683370190505b50905060005b82518110156117555782818151811061171a5761171a613bd2565b602002602001015182828151811061173457611734613bd2565b67ffffffffffffffff909216602092830291909101909101526001016116ff565b5092915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff8216600090815260076020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526109c990612670565b60095473ffffffffffffffffffffffffffffffffffffffff16331480159061186e575060015473ffffffffffffffffffffffffffffffffffffffff163314155b156118a7576040517f8e4a23d600000000000000000000000000000000000000000000000000000000815233600482015260240161080d565b610d0c838383612722565b6118ba611dd8565b60005b83811015611aa75760008585838181106118d9576118d9613bd2565b90506020020160208101906118ee9190613873565b9050611905600567ffffffffffffffff8316612664565b611947576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080d565b67ffffffffffffffff8116600090815260076020526040812061196c90600501612657565b905060005b81518110156119d8576119cf82828151811061198f5761198f613bd2565b6020026020010151600760008667ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060050161266490919063ffffffff16565b50600101611971565b5067ffffffffffffffff8216600090815260076020526040812080547fffffffffffffffffffffff00000000000000000000000000000000000000000090811682556001820183905560028201805490911690556003810182905590611a41600483018261350a565b6005820160008181611a538282613544565b505060405167ffffffffffffffff871681527f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d85991694506020019250611a95915050565b60405180910390a150506001016118bd565b5060005b81811015611dbd576000838383818110611ac757611ac7613bd2565b9050602002810190611ad99190614035565b611ae290614112565b9050611af38160600151600061280c565b611b028160800151600061280c565b806040015151600003611b41576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051611b599060059067ffffffffffffffff16612949565b611b9e5780516040517f1d5ad3c500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161080d565b805167ffffffffffffffff16600090815260076020908152604091829020825160a08082018552606080870180518601516fffffffffffffffffffffffffffffffff90811680865263ffffffff42168689018190528351511515878b0181905284518a0151841686890181905294518b0151841660809889018190528954740100000000000000000000000000000000000000009283027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7001000000000000000000000000000000008087027fffffffffffffffffffffffff000000000000000000000000000000000000000094851690981788178216929092178d5592810290971760018c01558c519889018d52898e0180518d01518716808b528a8e019590955280515115158a8f018190528151909d01518716988a01899052518d0151909516979098018790526002890180549a909102999093161717909416959095179092559092029091176003820155908201516004820190611d21908261421a565b5060005b826020015151811015611d6557611d5d836000015184602001518381518110611d5057611d50613bd2565b60200260200101516123d1565b600101611d25565b507f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c28260000151836040015184606001518560800151604051611dab9493929190614334565b60405180910390a15050600101611aab565b5050505050565b611dcc611dd8565b611dd581612955565b50565b60015473ffffffffffffffffffffffffffffffffffffffff163314611e29576040517f2b5c74de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b611e3e61032060a08301608084016136c7565b611e9d57611e5260a08201608083016136c7565b6040517f961c9a4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161080d565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb611ee96040840160208501613873565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa158015611f5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7e9190613efe565b15611fb5576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611fcd611fc86040830160208401613873565b612a19565b611fed611fe06040830160208401613873565b6103c060a0840184613d16565b61203257611ffe60a0820182613d16565b6040517f24eb47e500000000000000000000000000000000000000000000000000000000815260040161080d929190613f74565b611dd56120456040830160208401613873565b8260600135612b3f565b600482015163ffffffff81161561209a576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff8216600482015260240161080d565b6008830151600c8401516014850151602085015163ffffffff8085169116146121055760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff9182166004820152908416602482015260440161080d565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff161461219a576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161080d565b845167ffffffffffffffff8281169116146121f85784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9182166004820152908216602482015260440161080d565b505050505050565b600081815260018301602052604081205415155b9392505050565b7f0000000000000000000000000000000000000000000000000000000000000000612272576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561230857600083828151811061229257612292613bd2565b602002602001015190506122b0816002612b8690919063ffffffff16565b156122ff5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50600101612275565b5060005b8151811015610d0c57600082828151811061232957612329613bd2565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361236d57506123c9565b612378600282612ba8565b156123c75760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b60010161230c565b805160000361240c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805160208083019190912067ffffffffffffffff841660009081526007909252604090912061243e9060050182612949565b6124785782826040517f393b8ad200000000000000000000000000000000000000000000000000000000815260040161080d9291906143cd565b6000818152600860205260409020612490838261421a565b508267ffffffffffffffff167f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea8360405161143e9190613692565b6124de61032060a08301608084016136c7565b6124f257611e5260a08201608083016136c7565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632cbc26bb61253e6040840160208501613873565b60405160e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016815260809190911b77ffffffffffffffff00000000000000000000000000000000166004820152602401602060405180830381865afa1580156125af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d39190613efe565b1561260a576040517f53ad11d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61262261261d60608301604084016136c7565b612bca565b61263a6126356040830160208401613873565b612c49565b611dd561264d6040830160208401613873565b8260600135612d97565b6060600061221483612ddb565b60006122148383612e36565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526126fe82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426126e2919061441f565b85608001516fffffffffffffffffffffffffffffffff16612f29565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b61272b83610e60565b61276d576040517f1e670e4b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8416600482015260240161080d565b61277882600061280c565b67ffffffffffffffff8316600090815260076020526040902061279b9083612f51565b6127a681600061280c565b67ffffffffffffffff831660009081526007602052604090206127cc9060020182612f51565b7f0350d63aa5f270e01729d00d627eeb8f3429772b1818c016c66a588a864f912b8383836040516127ff93929190614432565b60405180910390a1505050565b8151156128d75781602001516fffffffffffffffffffffffffffffffff1682604001516fffffffffffffffffffffffffffffffff16101580612862575060408201516fffffffffffffffffffffffffffffffff16155b1561289b57816040517f8020d12400000000000000000000000000000000000000000000000000000000815260040161080d91906144b5565b80156128d3576040517f433fc33d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60408201516fffffffffffffffffffffffffffffffff16151580612910575060208201516fffffffffffffffffffffffffffffffff1615155b156128d357816040517fd68af9cc00000000000000000000000000000000000000000000000000000000815260040161080d91906144b5565b600061221483836130f3565b3373ffffffffffffffffffffffffffffffffffffffff8216036129a4576040517fdad89dca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b612a2281610e60565b612a64576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080d565b600480546040517f83826b2b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925233602483015273ffffffffffffffffffffffffffffffffffffffff16906383826b2b90604401602060405180830381865afa158015612ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b079190613efe565b611dd5576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161080d565b67ffffffffffffffff821660009081526007602052604090206128d390600201827f0000000000000000000000000000000000000000000000000000000000000000613142565b60006122148373ffffffffffffffffffffffffffffffffffffffff8416612e36565b60006122148373ffffffffffffffffffffffffffffffffffffffff84166130f3565b7f000000000000000000000000000000000000000000000000000000000000000015611dd557612bfb6002826134c5565b611dd5576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161080d565b612c5281610e60565b612c94576040517fa9902c7e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8216600482015260240161080d565b600480546040517fa8d87a3b00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84169281019290925273ffffffffffffffffffffffffffffffffffffffff169063a8d87a3b90602401602060405180830381865afa158015612d0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d3191906144f1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611dd5576040517f728fe07b00000000000000000000000000000000000000000000000000000000815233600482015260240161080d565b67ffffffffffffffff821660009081526007602052604090206128d390827f0000000000000000000000000000000000000000000000000000000000000000613142565b6060816000018054806020026020016040519081016040528092919081815260200182805480156115c457602002820191906000526020600020905b815481526020019060010190808311612e175750505050509050919050565b60008181526001830160205260408120548015612f1f576000612e5a60018361441f565b8554909150600090612e6e9060019061441f565b9050808214612ed3576000866000018281548110612e8e57612e8e613bd2565b9060005260206000200154905080876000018481548110612eb157612eb1613bd2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ee457612ee461450e565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506109c9565b60009150506109c9565b6000612f4885612f39848661453d565b612f439087614554565b6134f4565b95945050505050565b8154600090612f7a90700100000000000000000000000000000000900463ffffffff164261441f565b9050801561301c5760018301548354612fc2916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416612f29565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354613042916fffffffffffffffffffffffffffffffff90811691166134f4565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906127ff9084906144b5565b600081815260018301602052604081205461313a575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109c9565b5060006109c9565b825474010000000000000000000000000000000000000000900460ff161580613169575081155b1561317357505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906131b990700100000000000000000000000000000000900463ffffffff164261441f565b9050801561327957818311156131fb576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546132359083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16612f29565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156133305773ffffffffffffffffffffffffffffffffffffffff84166132d8576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161080d565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161080d565b848310156134435760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290613374908261441f565b61337e878a61441f565b6133889190614554565b6133929190614567565b905073ffffffffffffffffffffffffffffffffffffffff86166133eb576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161080d565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161080d565b61344d858461441f565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515612214565b60008183106135035781612214565b5090919050565b50805461351690613fbe565b6000825580601f10613526575050565b601f016020900490600052602060002090810190611dd5919061355e565b5080546000825590600052602060002090810190611dd591905b5b80821115613573576000815560010161355f565b5090565b6000806020838503121561358a57600080fd5b823567ffffffffffffffff808211156135a257600080fd5b818501915085601f8301126135b657600080fd5b8135818111156135c557600080fd5b8660208260071b85010111156135da57600080fd5b60209290920196919550909350505050565b6000602082840312156135fe57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461221457600080fd5b6000815180845260005b8181101561365457602081850181015186830182015201613638565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000612214602083018461362e565b73ffffffffffffffffffffffffffffffffffffffff81168114611dd557600080fd5b6000602082840312156136d957600080fd5b8135612214816136a5565b6000602082840312156136f657600080fd5b813567ffffffffffffffff81111561370d57600080fd5b8201610100818503121561221457600080fd5b67ffffffffffffffff81168114611dd557600080fd5b60008060006040848603121561374b57600080fd5b833561375681613720565b9250602084013567ffffffffffffffff8082111561377357600080fd5b818601915086601f83011261378757600080fd5b81358181111561379657600080fd5b8760208285010111156137a857600080fd5b6020830194508093505050509250925092565b60008083601f8401126137cd57600080fd5b50813567ffffffffffffffff8111156137e557600080fd5b6020830191508360208260051b850101111561380057600080fd5b9250929050565b6000806000806040858703121561381d57600080fd5b843567ffffffffffffffff8082111561383557600080fd5b613841888389016137bb565b9096509450602087013591508082111561385a57600080fd5b50613867878288016137bb565b95989497509550505050565b60006020828403121561388557600080fd5b813561221481613720565b6000602082840312156138a257600080fd5b813567ffffffffffffffff8111156138b957600080fd5b820160a0818503121561221457600080fd5b6020815260008251604060208401526138e7606084018261362e565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0848303016040850152612f48828261362e565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015613997577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261398585835161362e565b9450928501929085019060010161394b565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156139f257835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016139c0565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156139f257835167ffffffffffffffff1683529284019291840191600101613a1a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715613a9257613a92613a40565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613adf57613adf613a40565b604052919050565b8015158114611dd557600080fd5b80356fffffffffffffffffffffffffffffffff81168114613b1557600080fd5b919050565b600060608284031215613b2c57600080fd5b6040516060810181811067ffffffffffffffff82111715613b4f57613b4f613a40565b6040529050808235613b6081613ae7565b8152613b6e60208401613af5565b6020820152613b7f60408401613af5565b60408201525092915050565b600080600060e08486031215613ba057600080fd5b8335613bab81613720565b9250613bba8560208601613b1a565b9150613bc98560808601613b1a565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803563ffffffff81168114613b1557600080fd5b600060808284031215613c2757600080fd5b6040516080810181811067ffffffffffffffff82111715613c4a57613c4a613a40565b60405282358152613c5d60208401613c01565b60208201526040830135613c7081613720565b60408201526060830135613c8381613ae7565b60608201529392505050565b6020808252818101839052600090604080840186845b87811015613d09578135835263ffffffff613cc1868401613c01565b168584015283820135613cd381613720565b67ffffffffffffffff1683850152606082810135613cf081613ae7565b1515908401526080928301929190910190600101613ca5565b5090979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613d4b57600080fd5b83018035915067ffffffffffffffff821115613d6657600080fd5b60200191503681900382131561380057600080fd5b600060408284031215613d8d57600080fd5b613d95613a6f565b8235613da081613720565b8152613dae60208401613c01565b60208201529392505050565b600082601f830112613dcb57600080fd5b813567ffffffffffffffff811115613de557613de5613a40565b613e1660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613a98565b818152846020838601011115613e2b57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613e5a57600080fd5b813567ffffffffffffffff80821115613e7257600080fd5b9083019060408286031215613e8657600080fd5b613e8e613a6f565b823582811115613e9d57600080fd5b613ea987828601613dba565b825250602083013582811115613ebe57600080fd5b613eca87828601613dba565b60208301525095945050505050565b604081526000613eec604083018561362e565b8281036020840152612f48818561362e565b600060208284031215613f1057600080fd5b815161221481613ae7565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000610bf6602083018486613f2b565b600060208284031215613f9a57600080fd5b5035919050565b600060208284031215613fb357600080fd5b815161221481613720565b600181811c90821680613fd257607f821691505b60208210810361400b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b67ffffffffffffffff84168152604060208201526000612f48604083018486613f2b565b600082357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee183360301811261406957600080fd5b9190910192915050565b600082601f83011261408457600080fd5b8135602067ffffffffffffffff808311156140a1576140a1613a40565b8260051b6140b0838201613a98565b93845285810183019383810190888611156140ca57600080fd5b84880192505b85831015614106578235848111156140e85760008081fd5b6140f68a87838c0101613dba565b83525091840191908401906140d0565b98975050505050505050565b6000610120823603121561412557600080fd5b60405160a0810167ffffffffffffffff828210818311171561414957614149613a40565b816040528435915061415a82613720565b9082526020840135908082111561417057600080fd5b61417c36838701614073565b6020840152604085013591508082111561419557600080fd5b506141a236828601613dba565b6040830152506141b53660608501613b1a565b60608201526141c73660c08501613b1a565b608082015292915050565b601f821115610d0c576000816000526020600020601f850160051c810160208610156141fb5750805b601f850160051c820191505b818110156121f857828155600101614207565b815167ffffffffffffffff81111561423457614234613a40565b614248816142428454613fbe565b846141d2565b602080601f83116001811461429b57600084156142655750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556121f8565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142e8578886015182559484019460019091019084016142c9565b508582101561432457878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600061010067ffffffffffffffff871683528060208401526143588184018761362e565b8551151560408581019190915260208701516fffffffffffffffffffffffffffffffff90811660608701529087015116608085015291506143969050565b8251151560a083015260208301516fffffffffffffffffffffffffffffffff90811660c084015260408401511660e0830152612f48565b67ffffffffffffffff83168152604060208201526000610bf6604083018461362e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109c9576109c96143f0565b67ffffffffffffffff8416815260e0810161447e60208301858051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b82511515608083015260208301516fffffffffffffffffffffffffffffffff90811660a084015260408401511660c0830152610bf6565b606081016109c982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561450357600080fd5b8151612214816136a5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b80820281158282048414176109c9576109c96143f0565b808201808211156109c9576109c96143f0565b60008261459d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea164736f6c6343000818000a", } var USDCTokenPoolABI = USDCTokenPoolMetaData.ABI @@ -389,26 +388,26 @@ func (_USDCTokenPool *USDCTokenPoolCallerSession) GetRateLimitAdmin() (common.Ad return _USDCTokenPool.Contract.GetRateLimitAdmin(&_USDCTokenPool.CallOpts) } -func (_USDCTokenPool *USDCTokenPoolCaller) GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { +func (_USDCTokenPool *USDCTokenPoolCaller) GetRemotePools(opts *bind.CallOpts, remoteChainSelector uint64) ([][]byte, error) { var out []interface{} - err := _USDCTokenPool.contract.Call(opts, &out, "getRemotePool", remoteChainSelector) + err := _USDCTokenPool.contract.Call(opts, &out, "getRemotePools", remoteChainSelector) if err != nil { - return *new([]byte), err + return *new([][]byte), err } - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + out0 := *abi.ConvertType(out[0], new([][]byte)).(*[][]byte) return out0, err } -func (_USDCTokenPool *USDCTokenPoolSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { - return _USDCTokenPool.Contract.GetRemotePool(&_USDCTokenPool.CallOpts, remoteChainSelector) +func (_USDCTokenPool *USDCTokenPoolSession) GetRemotePools(remoteChainSelector uint64) ([][]byte, error) { + return _USDCTokenPool.Contract.GetRemotePools(&_USDCTokenPool.CallOpts, remoteChainSelector) } -func (_USDCTokenPool *USDCTokenPoolCallerSession) GetRemotePool(remoteChainSelector uint64) ([]byte, error) { - return _USDCTokenPool.Contract.GetRemotePool(&_USDCTokenPool.CallOpts, remoteChainSelector) +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetRemotePools(remoteChainSelector uint64) ([][]byte, error) { + return _USDCTokenPool.Contract.GetRemotePools(&_USDCTokenPool.CallOpts, remoteChainSelector) } func (_USDCTokenPool *USDCTokenPoolCaller) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) { @@ -521,6 +520,28 @@ func (_USDCTokenPool *USDCTokenPoolCallerSession) GetToken() (common.Address, er return _USDCTokenPool.Contract.GetToken(&_USDCTokenPool.CallOpts) } +func (_USDCTokenPool *USDCTokenPoolCaller) GetTokenDecimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "getTokenDecimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) GetTokenDecimals() (uint8, error) { + return _USDCTokenPool.Contract.GetTokenDecimals(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) GetTokenDecimals() (uint8, error) { + return _USDCTokenPool.Contract.GetTokenDecimals(&_USDCTokenPool.CallOpts) +} + func (_USDCTokenPool *USDCTokenPoolCaller) ILocalDomainIdentifier(opts *bind.CallOpts) (uint32, error) { var out []interface{} err := _USDCTokenPool.contract.Call(opts, &out, "i_localDomainIdentifier") @@ -587,6 +608,28 @@ func (_USDCTokenPool *USDCTokenPoolCallerSession) ITokenMessenger() (common.Addr return _USDCTokenPool.Contract.ITokenMessenger(&_USDCTokenPool.CallOpts) } +func (_USDCTokenPool *USDCTokenPoolCaller) IsRemotePool(opts *bind.CallOpts, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "isRemotePool", remoteChainSelector, remotePoolAddress) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) IsRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + return _USDCTokenPool.Contract.IsRemotePool(&_USDCTokenPool.CallOpts, remoteChainSelector, remotePoolAddress) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) IsRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { + return _USDCTokenPool.Contract.IsRemotePool(&_USDCTokenPool.CallOpts, remoteChainSelector, remotePoolAddress) +} + func (_USDCTokenPool *USDCTokenPoolCaller) IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) { var out []interface{} err := _USDCTokenPool.contract.Call(opts, &out, "isSupportedChain", remoteChainSelector) @@ -709,6 +752,18 @@ func (_USDCTokenPool *USDCTokenPoolTransactorSession) AcceptOwnership() (*types. return _USDCTokenPool.Contract.AcceptOwnership(&_USDCTokenPool.TransactOpts) } +func (_USDCTokenPool *USDCTokenPoolTransactor) AddRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "addRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_USDCTokenPool *USDCTokenPoolSession) AddRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _USDCTokenPool.Contract.AddRemotePool(&_USDCTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) AddRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _USDCTokenPool.Contract.AddRemotePool(&_USDCTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + func (_USDCTokenPool *USDCTokenPoolTransactor) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) { return _USDCTokenPool.contract.Transact(opts, "applyAllowListUpdates", removes, adds) } @@ -721,16 +776,16 @@ func (_USDCTokenPool *USDCTokenPoolTransactorSession) ApplyAllowListUpdates(remo return _USDCTokenPool.Contract.ApplyAllowListUpdates(&_USDCTokenPool.TransactOpts, removes, adds) } -func (_USDCTokenPool *USDCTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _USDCTokenPool.contract.Transact(opts, "applyChainUpdates", chains) +func (_USDCTokenPool *USDCTokenPoolTransactor) ApplyChainUpdates(opts *bind.TransactOpts, remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "applyChainUpdates", remoteChainSelectorsToRemove, chainsToAdd) } -func (_USDCTokenPool *USDCTokenPoolSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _USDCTokenPool.Contract.ApplyChainUpdates(&_USDCTokenPool.TransactOpts, chains) +func (_USDCTokenPool *USDCTokenPoolSession) ApplyChainUpdates(remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ApplyChainUpdates(&_USDCTokenPool.TransactOpts, remoteChainSelectorsToRemove, chainsToAdd) } -func (_USDCTokenPool *USDCTokenPoolTransactorSession) ApplyChainUpdates(chains []TokenPoolChainUpdate) (*types.Transaction, error) { - return _USDCTokenPool.Contract.ApplyChainUpdates(&_USDCTokenPool.TransactOpts, chains) +func (_USDCTokenPool *USDCTokenPoolTransactorSession) ApplyChainUpdates(remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) { + return _USDCTokenPool.Contract.ApplyChainUpdates(&_USDCTokenPool.TransactOpts, remoteChainSelectorsToRemove, chainsToAdd) } func (_USDCTokenPool *USDCTokenPoolTransactor) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) { @@ -757,6 +812,18 @@ func (_USDCTokenPool *USDCTokenPoolTransactorSession) ReleaseOrMint(releaseOrMin return _USDCTokenPool.Contract.ReleaseOrMint(&_USDCTokenPool.TransactOpts, releaseOrMintIn) } +func (_USDCTokenPool *USDCTokenPoolTransactor) RemoveRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _USDCTokenPool.contract.Transact(opts, "removeRemotePool", remoteChainSelector, remotePoolAddress) +} + +func (_USDCTokenPool *USDCTokenPoolSession) RemoveRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _USDCTokenPool.Contract.RemoveRemotePool(&_USDCTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + +func (_USDCTokenPool *USDCTokenPoolTransactorSession) RemoveRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { + return _USDCTokenPool.Contract.RemoveRemotePool(&_USDCTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) +} + func (_USDCTokenPool *USDCTokenPoolTransactor) SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) { return _USDCTokenPool.contract.Transact(opts, "setChainRateLimiterConfig", remoteChainSelector, outboundConfig, inboundConfig) } @@ -793,18 +860,6 @@ func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetRateLimitAdmin(rateLimi return _USDCTokenPool.Contract.SetRateLimitAdmin(&_USDCTokenPool.TransactOpts, rateLimitAdmin) } -func (_USDCTokenPool *USDCTokenPoolTransactor) SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _USDCTokenPool.contract.Transact(opts, "setRemotePool", remoteChainSelector, remotePoolAddress) -} - -func (_USDCTokenPool *USDCTokenPoolSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _USDCTokenPool.Contract.SetRemotePool(&_USDCTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) -} - -func (_USDCTokenPool *USDCTokenPoolTransactorSession) SetRemotePool(remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) { - return _USDCTokenPool.Contract.SetRemotePool(&_USDCTokenPool.TransactOpts, remoteChainSelector, remotePoolAddress) -} - func (_USDCTokenPool *USDCTokenPoolTransactor) SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) { return _USDCTokenPool.contract.Transact(opts, "setRouter", newRouter) } @@ -2689,8 +2744,136 @@ func (_USDCTokenPool *USDCTokenPoolFilterer) ParseReleased(log types.Log) (*USDC return event, nil } -type USDCTokenPoolRemotePoolSetIterator struct { - Event *USDCTokenPoolRemotePoolSet +type USDCTokenPoolRemotePoolAddedIterator struct { + Event *USDCTokenPoolRemotePoolAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *USDCTokenPoolRemotePoolAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolRemotePoolAdded) + 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 + } + } + + select { + case log := <-it.logs: + it.Event = new(USDCTokenPoolRemotePoolAdded) + 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() + } +} + +func (it *USDCTokenPoolRemotePoolAddedIterator) Error() error { + return it.fail +} + +func (it *USDCTokenPoolRemotePoolAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type USDCTokenPoolRemotePoolAdded struct { + RemoteChainSelector uint64 + RemotePoolAddress []byte + Raw types.Log +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterRemotePoolAdded(opts *bind.FilterOpts, remoteChainSelector []uint64) (*USDCTokenPoolRemotePoolAddedIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "RemotePoolAdded", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &USDCTokenPoolRemotePoolAddedIterator{contract: _USDCTokenPool.contract, event: "RemotePoolAdded", logs: logs, sub: sub}, nil +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchRemotePoolAdded(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolRemotePoolAdded, remoteChainSelector []uint64) (event.Subscription, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "RemotePoolAdded", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(USDCTokenPoolRemotePoolAdded) + if err := _USDCTokenPool.contract.UnpackLog(event, "RemotePoolAdded", 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 +} + +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseRemotePoolAdded(log types.Log) (*USDCTokenPoolRemotePoolAdded, error) { + event := new(USDCTokenPoolRemotePoolAdded) + if err := _USDCTokenPool.contract.UnpackLog(event, "RemotePoolAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type USDCTokenPoolRemotePoolRemovedIterator struct { + Event *USDCTokenPoolRemotePoolRemoved contract *bind.BoundContract event string @@ -2701,7 +2884,7 @@ type USDCTokenPoolRemotePoolSetIterator struct { fail error } -func (it *USDCTokenPoolRemotePoolSetIterator) Next() bool { +func (it *USDCTokenPoolRemotePoolRemovedIterator) Next() bool { if it.fail != nil { return false @@ -2710,7 +2893,7 @@ func (it *USDCTokenPoolRemotePoolSetIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(USDCTokenPoolRemotePoolSet) + it.Event = new(USDCTokenPoolRemotePoolRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2725,7 +2908,7 @@ func (it *USDCTokenPoolRemotePoolSetIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(USDCTokenPoolRemotePoolSet) + it.Event = new(USDCTokenPoolRemotePoolRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2740,44 +2923,43 @@ func (it *USDCTokenPoolRemotePoolSetIterator) Next() bool { } } -func (it *USDCTokenPoolRemotePoolSetIterator) Error() error { +func (it *USDCTokenPoolRemotePoolRemovedIterator) Error() error { return it.fail } -func (it *USDCTokenPoolRemotePoolSetIterator) Close() error { +func (it *USDCTokenPoolRemotePoolRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -type USDCTokenPoolRemotePoolSet struct { +type USDCTokenPoolRemotePoolRemoved struct { RemoteChainSelector uint64 - PreviousPoolAddress []byte RemotePoolAddress []byte Raw types.Log } -func (_USDCTokenPool *USDCTokenPoolFilterer) FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*USDCTokenPoolRemotePoolSetIterator, error) { +func (_USDCTokenPool *USDCTokenPoolFilterer) FilterRemotePoolRemoved(opts *bind.FilterOpts, remoteChainSelector []uint64) (*USDCTokenPoolRemotePoolRemovedIterator, error) { var remoteChainSelectorRule []interface{} for _, remoteChainSelectorItem := range remoteChainSelector { remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + logs, sub, err := _USDCTokenPool.contract.FilterLogs(opts, "RemotePoolRemoved", remoteChainSelectorRule) if err != nil { return nil, err } - return &USDCTokenPoolRemotePoolSetIterator{contract: _USDCTokenPool.contract, event: "RemotePoolSet", logs: logs, sub: sub}, nil + return &USDCTokenPoolRemotePoolRemovedIterator{contract: _USDCTokenPool.contract, event: "RemotePoolRemoved", logs: logs, sub: sub}, nil } -func (_USDCTokenPool *USDCTokenPoolFilterer) WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) { +func (_USDCTokenPool *USDCTokenPoolFilterer) WatchRemotePoolRemoved(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolRemotePoolRemoved, remoteChainSelector []uint64) (event.Subscription, error) { var remoteChainSelectorRule []interface{} for _, remoteChainSelectorItem := range remoteChainSelector { remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "RemotePoolSet", remoteChainSelectorRule) + logs, sub, err := _USDCTokenPool.contract.WatchLogs(opts, "RemotePoolRemoved", remoteChainSelectorRule) if err != nil { return nil, err } @@ -2787,8 +2969,8 @@ func (_USDCTokenPool *USDCTokenPoolFilterer) WatchRemotePoolSet(opts *bind.Watch select { case log := <-logs: - event := new(USDCTokenPoolRemotePoolSet) - if err := _USDCTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { + event := new(USDCTokenPoolRemotePoolRemoved) + if err := _USDCTokenPool.contract.UnpackLog(event, "RemotePoolRemoved", log); err != nil { return err } event.Raw = log @@ -2809,9 +2991,9 @@ func (_USDCTokenPool *USDCTokenPoolFilterer) WatchRemotePoolSet(opts *bind.Watch }), nil } -func (_USDCTokenPool *USDCTokenPoolFilterer) ParseRemotePoolSet(log types.Log) (*USDCTokenPoolRemotePoolSet, error) { - event := new(USDCTokenPoolRemotePoolSet) - if err := _USDCTokenPool.contract.UnpackLog(event, "RemotePoolSet", log); err != nil { +func (_USDCTokenPool *USDCTokenPoolFilterer) ParseRemotePoolRemoved(log types.Log) (*USDCTokenPoolRemotePoolRemoved, error) { + event := new(USDCTokenPoolRemotePoolRemoved) + if err := _USDCTokenPool.contract.UnpackLog(event, "RemotePoolRemoved", log); err != nil { return nil, err } event.Raw = log @@ -3085,8 +3267,10 @@ func (_USDCTokenPool *USDCTokenPool) ParseLog(log types.Log) (generated.AbigenLo return _USDCTokenPool.ParseRateLimitAdminSet(log) case _USDCTokenPool.abi.Events["Released"].ID: return _USDCTokenPool.ParseReleased(log) - case _USDCTokenPool.abi.Events["RemotePoolSet"].ID: - return _USDCTokenPool.ParseRemotePoolSet(log) + case _USDCTokenPool.abi.Events["RemotePoolAdded"].ID: + return _USDCTokenPool.ParseRemotePoolAdded(log) + case _USDCTokenPool.abi.Events["RemotePoolRemoved"].ID: + return _USDCTokenPool.ParseRemotePoolRemoved(log) case _USDCTokenPool.abi.Events["RouterUpdated"].ID: return _USDCTokenPool.ParseRouterUpdated(log) case _USDCTokenPool.abi.Events["TokensConsumed"].ID: @@ -3157,8 +3341,12 @@ func (USDCTokenPoolReleased) Topic() common.Hash { return common.HexToHash("0x2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f52") } -func (USDCTokenPoolRemotePoolSet) Topic() common.Hash { - return common.HexToHash("0xdb4d6220746a38cbc5335f7e108f7de80f482f4d23350253dfd0917df75a14bf") +func (USDCTokenPoolRemotePoolAdded) Topic() common.Hash { + return common.HexToHash("0x7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea") +} + +func (USDCTokenPoolRemotePoolRemoved) Topic() common.Hash { + return common.HexToHash("0x52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d76") } func (USDCTokenPoolRouterUpdated) Topic() common.Hash { @@ -3188,7 +3376,7 @@ type USDCTokenPoolInterface interface { GetRateLimitAdmin(opts *bind.CallOpts) (common.Address, error) - GetRemotePool(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) + GetRemotePools(opts *bind.CallOpts, remoteChainSelector uint64) ([][]byte, error) GetRemoteToken(opts *bind.CallOpts, remoteChainSelector uint64) ([]byte, error) @@ -3200,12 +3388,16 @@ type USDCTokenPoolInterface interface { GetToken(opts *bind.CallOpts) (common.Address, error) + GetTokenDecimals(opts *bind.CallOpts) (uint8, error) + ILocalDomainIdentifier(opts *bind.CallOpts) (uint32, error) IMessageTransmitter(opts *bind.CallOpts) (common.Address, error) ITokenMessenger(opts *bind.CallOpts) (common.Address, error) + IsRemotePool(opts *bind.CallOpts, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) + IsSupportedChain(opts *bind.CallOpts, remoteChainSelector uint64) (bool, error) IsSupportedToken(opts *bind.CallOpts, token common.Address) (bool, error) @@ -3218,22 +3410,24 @@ type USDCTokenPoolInterface interface { AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + AddRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) - ApplyChainUpdates(opts *bind.TransactOpts, chains []TokenPoolChainUpdate) (*types.Transaction, error) + ApplyChainUpdates(opts *bind.TransactOpts, remoteChainSelectorsToRemove []uint64, chainsToAdd []TokenPoolChainUpdate) (*types.Transaction, error) LockOrBurn(opts *bind.TransactOpts, lockOrBurnIn PoolLockOrBurnInV1) (*types.Transaction, error) ReleaseOrMint(opts *bind.TransactOpts, releaseOrMintIn PoolReleaseOrMintInV1) (*types.Transaction, error) + RemoveRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) + SetChainRateLimiterConfig(opts *bind.TransactOpts, remoteChainSelector uint64, outboundConfig RateLimiterConfig, inboundConfig RateLimiterConfig) (*types.Transaction, error) SetDomains(opts *bind.TransactOpts, domains []USDCTokenPoolDomainUpdate) (*types.Transaction, error) SetRateLimitAdmin(opts *bind.TransactOpts, rateLimitAdmin common.Address) (*types.Transaction, error) - SetRemotePool(opts *bind.TransactOpts, remoteChainSelector uint64, remotePoolAddress []byte) (*types.Transaction, error) - SetRouter(opts *bind.TransactOpts, newRouter common.Address) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) @@ -3328,11 +3522,17 @@ type USDCTokenPoolInterface interface { ParseReleased(log types.Log) (*USDCTokenPoolReleased, error) - FilterRemotePoolSet(opts *bind.FilterOpts, remoteChainSelector []uint64) (*USDCTokenPoolRemotePoolSetIterator, error) + FilterRemotePoolAdded(opts *bind.FilterOpts, remoteChainSelector []uint64) (*USDCTokenPoolRemotePoolAddedIterator, error) + + WatchRemotePoolAdded(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolRemotePoolAdded, remoteChainSelector []uint64) (event.Subscription, error) + + ParseRemotePoolAdded(log types.Log) (*USDCTokenPoolRemotePoolAdded, error) + + FilterRemotePoolRemoved(opts *bind.FilterOpts, remoteChainSelector []uint64) (*USDCTokenPoolRemotePoolRemovedIterator, error) - WatchRemotePoolSet(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolRemotePoolSet, remoteChainSelector []uint64) (event.Subscription, error) + WatchRemotePoolRemoved(opts *bind.WatchOpts, sink chan<- *USDCTokenPoolRemotePoolRemoved, remoteChainSelector []uint64) (event.Subscription, error) - ParseRemotePoolSet(log types.Log) (*USDCTokenPoolRemotePoolSet, error) + ParseRemotePoolRemoved(log types.Log) (*USDCTokenPoolRemotePoolRemoved, error) FilterRouterUpdated(opts *bind.FilterOpts) (*USDCTokenPoolRouterUpdatedIterator, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 47aeb6db587..5d381c6db67 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,13 +1,13 @@ GETH_VERSION: 1.14.11 -burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin d5a1028728ed52d3c12ccd0e2f54d536697a6d5f689b0e89a4d083011a8cb1f6 -burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin 7f6b367ccf37878317fd9f50488370770204f0cc10c6e0e576be7e7c4ca8db56 -burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin e136c9f7a1d7af46ed5bd5bb836317c97715a71ee024868251abd0c462f1f115 +burn_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnFromMintTokenPool/BurnFromMintTokenPool.bin 3be84751a3c43b6a8522e67368b69e1ec1b4271768c4c0fd9542ade23ce33306 +burn_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnMintTokenPool/BurnMintTokenPool.bin f44a858fed054ede21ae4af7ca66006c0993d9980b641dae2c6d3dc08471c936 +burn_with_from_mint_token_pool: ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.abi ../../../contracts/solc/v0.8.24/BurnWithFromMintTokenPool/BurnWithFromMintTokenPool.bin 0b825a9ea058cf2c72b75996bfe0e69f92e0e36b9af674abfe8fd036f5fa1a2c ccip_encoding_utils: ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.abi ../../../contracts/solc/v0.8.24/ICCIPEncodingUtils/ICCIPEncodingUtils.bin 9971fc93c34442a0989570d3dab90a125de31e6e60754ad972807ce6ad4dfba0 ccip_home: ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.abi ../../../contracts/solc/v0.8.24/CCIPHome/CCIPHome.bin 02cb75b4274a5be7f4006cf2b72cc09e77eb6dba4c1a9c720af86668ff8ea1df ccip_reader_tester: ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.abi ../../../contracts/solc/v0.8.24/CCIPReaderTester/CCIPReaderTester.bin 893c9930e874fe5235db24e28a22650c37f562da94fac93618566bcd84839fdc ether_sender_receiver: ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.abi ../../../contracts/solc/v0.8.24/EtherSenderReceiver/EtherSenderReceiver.bin 09510a3f773f108a3c231e8d202835c845ded862d071ec54c4f89c12d868b8de fee_quoter: ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.abi ../../../contracts/solc/v0.8.24/FeeQuoter/FeeQuoter.bin 8a0869d14bb5247fbc6d836fc20d123358373ed688e0d3b387d59e7d05496fea -lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin b30d5520449d57a4fffa3c3675e46d50ad29b066e09c16971153538a38ab25f7 +lock_release_token_pool: ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.24/LockReleaseTokenPool/LockReleaseTokenPool.bin 26dd99fa523446ff6857898d3aa14976660b4307a753de82541362a9ae33f292 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin d73956c26232ebcc4a5444429fa99cbefed960e323be9b5a24925885c2e477d5 message_hasher: ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.abi ../../../contracts/solc/v0.8.24/MessageHasher/MessageHasher.bin ec2d3a92348d8e7b8f0d359b62a45157b9d2c750c01fbcf991826c4392f6e218 mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMessenger/MockE2EUSDCTokenMessenger.bin d976651d36b33ac2196b32b9d2f4fa6690c6a18d41b621365659fce1c1d1e737 @@ -26,7 +26,7 @@ rmn_proxy_contract: ../../../contracts/solc/v0.8.24/ARMProxy/ARMProxy.abi ../../ rmn_remote: ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.abi ../../../contracts/solc/v0.8.24/RMNRemote/RMNRemote.bin faee0b0cdbe67f2e28deccf12acd4df13dd90992f6cbc0ba17bab845b8f4eb1c router: ../../../contracts/solc/v0.8.24/Router/Router.abi ../../../contracts/solc/v0.8.24/Router/Router.bin 2e4f0a7826c8abb49d882bb49fc5ff20a186dbd3137624b9097ffed903ae4888 token_admin_registry: ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.abi ../../../contracts/solc/v0.8.24/TokenAdminRegistry/TokenAdminRegistry.bin 397bc7be08c2848c0f4715f90b16206d6367f78ffb7cd48e2b1dfc0ccc5aea26 -token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin 7956641010fdb65dc2cf5cc1a51c5ed3e0c32493d6916eb563d24a855e827342 +token_pool: ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.abi ../../../contracts/solc/v0.8.24/TokenPool/TokenPool.bin e2d55e56f5401e8cb52fbf4c7dbc477548b5ca2f1d6a28561ebd523f42113c55 usdc_reader_tester: ../../../contracts/solc/v0.8.24/USDCReaderTester/USDCReaderTester.abi ../../../contracts/solc/v0.8.24/USDCReaderTester/USDCReaderTester.bin 672a07c9218fd6ad7c04dde583088b0f5ffc8d55a46f4be1714008dd3409438b -usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin da68b8ea71a12762d9fd3581cabddcb1c6f5b64a3fe3923842216dbf9d2aa9c6 +usdc_token_pool: ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.abi ../../../contracts/solc/v0.8.24/USDCTokenPool/USDCTokenPool.bin 0e49d3f0a8420c81a2136dbba66ed988a8ec0e975799e7c8ba83d163bb45313a weth9: ../../../contracts/solc/v0.8.24/WETH9/WETH9.abi ../../../contracts/solc/v0.8.24/WETH9/WETH9.bin 2970d79a0ca6dd6279cde130de45e56c8790ed695eae477fb5ba4c1bb75b720d diff --git a/core/gethwrappers/workflow/generated/workflow_registry_wrapper/workflow_registry_wrapper.go b/core/gethwrappers/workflow/generated/workflow_registry_wrapper/workflow_registry_wrapper.go index 008fffab28a..c87f59c0e7b 100644 --- a/core/gethwrappers/workflow/generated/workflow_registry_wrapper/workflow_registry_wrapper.go +++ b/core/gethwrappers/workflow/generated/workflow_registry_wrapper/workflow_registry_wrapper.go @@ -42,8 +42,8 @@ type WorkflowRegistryWorkflowMetadata struct { } var WorkflowRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AddressNotAuthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotWorkflowOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"}],\"name\":\"DONNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWorkflowID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryLocked\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"providedLength\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"maxAllowedLength\",\"type\":\"uint8\"}],\"name\":\"URLTooLong\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowAlreadyInDesiredStatus\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowContentNotUpdated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowIDAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowIDNotUpdated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"providedLength\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"maxAllowedLength\",\"type\":\"uint8\"}],\"name\":\"WorkflowNameTooLong\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32[]\",\"name\":\"donIDs\",\"type\":\"uint32[]\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"AllowedDONsUpdatedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"AuthorizedAddressesUpdatedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"lockedBy\",\"type\":\"address\"}],\"name\":\"RegistryLockedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"unlockedBy\",\"type\":\"address\"}],\"name\":\"RegistryUnlockedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"WorkflowActivatedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"WorkflowDeletedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"secretsURLHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"WorkflowForceUpdateSecretsRequestedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"WorkflowPausedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"WorkflowRegisteredV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"oldWorkflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newWorkflowID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"WorkflowUpdatedV1\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"workflowKey\",\"type\":\"bytes32\"}],\"name\":\"activateWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"computeHashKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"workflowKey\",\"type\":\"bytes32\"}],\"name\":\"deleteWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedDONs\",\"outputs\":[{\"internalType\":\"uint32[]\",\"name\":\"allowedDONs\",\"type\":\"uint32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"authorizedAddresses\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"getWorkflowMetadata\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"internalType\":\"structWorkflowRegistry.WorkflowMetadata\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"getWorkflowMetadataListByDON\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"internalType\":\"structWorkflowRegistry.WorkflowMetadata[]\",\"name\":\"workflowMetadataList\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"getWorkflowMetadataListByOwner\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"internalType\":\"structWorkflowRegistry.WorkflowMetadata[]\",\"name\":\"workflowMetadataList\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isRegistryLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lockRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"workflowKey\",\"type\":\"bytes32\"}],\"name\":\"pauseWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"registerWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"requestForceUpdateSecrets\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"donIDs\",\"type\":\"uint32[]\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"updateAllowedDONs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"updateAuthorizedAddresses\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"workflowKey\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"newWorkflowID\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"updateWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6080806040523461004a57331561003b57600180546001600160a01b03191633179055600a805460ff191690556040516133df90816100508239f35b639b15e16f60e01b8152600490fd5b600080fdfe6080604052600436101561001257600080fd5b60003560e01c806308e7f63a14612082578063181f5a7714611ff35780632303348a14611eb65780632b596f6d14611e2c5780633ccd14ff146114f2578063695e1340146113565780636f3517711461127d578063724c13dd146111865780637497066b1461106b57806379ba509714610f955780637ec0846d14610f0e5780638da5cb5b14610ebc5780639f4cb53414610e9b578063b87a019414610e45578063d4b89c7414610698578063db800092146105fd578063e3dce080146104d6578063e690f33214610362578063f2fde38b14610284578063f794bdeb146101495763f99ecb6b1461010357600080fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457602060ff600a54166040519015158152f35b600080fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760068054610185816123fc565b6101926040519182612283565b81815261019e826123fc565b916020937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060208401940136853760005b82811061023257505050906040519283926020840190602085525180915260408401929160005b82811061020557505050500390f35b835173ffffffffffffffffffffffffffffffffffffffff16855286955093810193928101926001016101f6565b6001908260005273ffffffffffffffffffffffffffffffffffffffff817ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01541661027d828761252e565b52016101cf565b346101445760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610144576102bb61236a565b6102c3612bc7565b73ffffffffffffffffffffffffffffffffffffffff8091169033821461033857817fffffffffffffffffffffffff00000000000000000000000000000000000000006000541617600055600154167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278600080a3005b60046040517fdad89dca000000000000000000000000000000000000000000000000000000008152fd5b346101445760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760ff600a54166104ac576103a760043533612dad565b600181019081549160ff8360c01c16600281101561047d576001146104535778010000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff841617905580547f6a0ed88e9cf3cb493ab4028fcb1dc7d18f0130fcdfba096edde0aadbfbf5e99f63ffffffff604051946020865260a01c16938061044e339560026020840191016125d0565b0390a4005b60046040517f6f861db1000000000000000000000000000000000000000000000000000000008152fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60046040517f78a4e7d9000000000000000000000000000000000000000000000000000000008152fd5b34610144576104e4366122f2565b916104ed612bc7565b60ff600a54166104ac5760005b828110610589575060405191806040840160408552526060830191906000905b8082106105515785151560208601527f509460cccbb176edde6cac28895a4415a24961b8f3a0bd2617b9bb7b4e166c9b85850386a1005b90919283359073ffffffffffffffffffffffffffffffffffffffff82168092036101445760019181526020809101940192019061051a565b60019084156105cb576105c373ffffffffffffffffffffffffffffffffffffffff6105bd6105b8848888612a67565b612ba6565b16612f88565b505b016104fa565b6105f773ffffffffffffffffffffffffffffffffffffffff6105f16105b8848888612a67565b166131b9565b506105c5565b346101445761061d61060e3661238d565b91610617612414565b50612a88565b6000526004602052604060002073ffffffffffffffffffffffffffffffffffffffff6001820154161561066e5761065661066a91612684565b604051918291602083526020830190612140565b0390f35b60046040517f871e01b2000000000000000000000000000000000000000000000000000000008152fd5b346101445760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760443567ffffffffffffffff8111610144576106e79036906004016122c4565b9060643567ffffffffffffffff8111610144576107089036906004016122c4565b9160843567ffffffffffffffff8111610144576107299036906004016122c4565b60ff600a94929454166104ac57610744818688602435612cbc565b61075060043533612dad565b9163ffffffff600184015460a01c169561076a3388612c12565b8354946024358614610e1b576107a56040516107948161078d8160038b016125d0565b0382612283565b61079f368c85612838565b90612e1c565b6107c76040516107bc8161078d8160048c016125d0565b61079f368688612838565b6107e96040516107de8161078d8160058d016125d0565b61079f36898d612838565b918080610e14575b80610e0d575b610de357602435885515610c8e575b15610b3d575b15610890575b926108807f41161473ce2ed633d9f902aab9702d16a5531da27ec84e1939abeffe54ad7353959361044e93610872610864978d604051998a996024358b5260a060208c0152600260a08c0191016125d0565b9189830360408b01526128fb565b9186830360608801526128fb565b90838203608085015233976128fb565b61089d600586015461257d565b610ad6575b67ffffffffffffffff8411610aa7576108cb846108c2600588015461257d565b600588016128b4565b6000601f85116001146109a757928492610872610880938a9b9c61094f876108649b9a61044e9a7f41161473ce2ed633d9f902aab9702d16a5531da27ec84e1939abeffe54ad73539e9f60009261099c575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60058a01555b8c8780610972575b50509c9b9a9950935050929495509250610812565b61097c9133612a88565b60005260056020526109946004356040600020612fda565b508c8761095d565b013590508f8061091d565b9860058601600052602060002060005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087168110610a8f5750926108726108809361044e969388968c7f41161473ce2ed633d9f902aab9702d16a5531da27ec84e1939abeffe54ad73539c9d9e9f897fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06108649e9d1610610a57575b505050600187811b0160058a0155610955565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88b60031b161c199101351690558e8d81610a44565b898c0135825560209b8c019b600190920191016109b7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516020810190610b1c81610af060058a01338661293a565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612283565b5190206000526005602052610b376004356040600020613280565b506108a2565b67ffffffffffffffff8311610aa757610b6683610b5d600489015461257d565b600489016128b4565b600083601f8111600114610bc75780610bb292600091610bbc575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b600487015561080c565b90508601358d610b81565b506004870160005260206000209060005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086168110610c765750847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610610c3e575b5050600183811b01600487015561080c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c19908601351690558a80610c2c565b9091602060018192858a013581550193019101610bd8565b67ffffffffffffffff8b11610aa757610cb78b610cae60038a015461257d565b60038a016128b4565b60008b601f8111600114610d175780610d0292600091610d0c57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b6003880155610806565b90508501358e610b81565b506003880160005260206000209060005b8d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081168210610dca578091507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610610d91575b905060018092501b016003880155610806565b60f87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9160031b161c19908501351690558b808c610d7e565b5085820135835560019092019160209182019101610d28565b60046040517f6b4a810d000000000000000000000000000000000000000000000000000000008152fd5b50826107f7565b50816107f1565b60046040517f95406722000000000000000000000000000000000000000000000000000000008152fd5b346101445760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445761066a610e8f610e8261236a565b6044359060243590612ae3565b604051918291826121e4565b34610144576020610eb4610eae3661238d565b91612a88565b604051908152f35b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457610f45612bc7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600a5416600a55337f11a03e25ee25bf1459f9e1cb293ea03707d84917f54a65e32c9a7be2f2edd68a600080a2005b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760005473ffffffffffffffffffffffffffffffffffffffff808216330361104157600154917fffffffffffffffffffffffff0000000000000000000000000000000000000000903382851617600155166000553391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60046040517f02b543c6000000000000000000000000000000000000000000000000000000008152fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457600880546110a7816123fc565b6110b46040519182612283565b8181526110c0826123fc565b916020937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060208401940136853760005b82811061114457505050906040519283926020840190602085525180915260408401929160005b82811061112757505050500390f35b835163ffffffff1685528695509381019392810192600101611118565b6001908260005263ffffffff817ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee301541661117f828761252e565b52016110f1565b3461014457611194366122f2565b9161119d612bc7565b60ff600a54166104ac5760005b828110611229575060405191806040840160408552526060830191906000905b8082106112015785151560208601527fcab63bf31d1e656baa23cebef64e12033ea0ffbd44b1278c3747beec2d2f618c85850386a1005b90919283359063ffffffff8216809203610144576001918152602080910194019201906111ca565b600190841561125b5761125363ffffffff61124d611248848888612a67565b612a77565b16612ecf565b505b016111aa565b61127763ffffffff611271611248848888612a67565b16613066565b50611255565b346101445760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760ff600a54166104ac576112c260043533612dad565b600181019081549163ffffffff8360a01c169260ff8160c01c16600281101561047d5715610453577fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff906113163386612c12565b16905580547f17b2d730bb5e064df3fbc6165c8aceb3b0d62c524c196c0bc1012209280bc9a6604051602081528061044e339560026020840191016125d0565b34610144576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610144576004359060ff600a54166104ac5761139e8233612dad565b63ffffffff600182015460a01c16926113c4336000526007602052604060002054151590565b156114c25733600052600283526113df816040600020613280565b5083600052600383526113f6816040600020613280565b5060058201611405815461257d565b61148e575b506000526004825261145160056040600020600081556000600182015561143360028201612a1e565b61143f60038201612a1e565b61144b60048201612a1e565b01612a1e565b7f76ee2dfcae10cb8522e62e713e62660e09ecfaab08db15d9404de1914132257161044e82549260405191829186835260023397840191016125d0565b6040516114a381610af087820194338661293a565b519020600052600583526114bb816040600020613280565b508461140a565b60246040517f85982a00000000000000000000000000000000000000000000000000000000008152336004820152fd5b346101445760e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760043567ffffffffffffffff8111610144576115419036906004016122c4565b6044359163ffffffff8316830361014457600260643510156101445760843567ffffffffffffffff81116101445761157d9036906004016122c4565b91909260a43567ffffffffffffffff8111610144576115a09036906004016122c4565b60c43567ffffffffffffffff8111610144576115c09036906004016122c4565b96909560ff600a54166104ac576115d7338a612c12565b60408511611df4576115ed888483602435612cbc565b6115f8858733612a88565b80600052600460205273ffffffffffffffffffffffffffffffffffffffff60016040600020015416611dca576040519061163182612266565b602435825233602083015263ffffffff8b16604083015261165760643560608401612571565b61166236888a612838565b6080830152611672368486612838565b60a0830152611682368688612838565b60c0830152611692368b8b612838565b60e0830152806000526004602052604060002091805183556001830173ffffffffffffffffffffffffffffffffffffffff60208301511681549077ffffffff0000000000000000000000000000000000000000604085015160a01b16906060850151600281101561047d5778ff0000000000000000000000000000000000000000000000007fffffffffffffff000000000000000000000000000000000000000000000000009160c01b1693161717179055608081015180519067ffffffffffffffff8211610aa7576117758261176c600288015461257d565b600288016128b4565b602090601f8311600114611cfe576117c2929160009183611c275750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60028401555b60a081015180519067ffffffffffffffff8211610aa7576117f9826117f0600388015461257d565b600388016128b4565b602090601f8311600114611c3257611846929160009183611c275750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60038401555b60c081015180519067ffffffffffffffff8211610aa75761187d82611874600488015461257d565b600488016128b4565b602090601f8311600114611b5a5791806118ce9260e09594600092611a355750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60048501555b015180519267ffffffffffffffff8411610aa757838d926119068e966118fd600586015461257d565b600586016128b4565b602090601f8311600114611a40579463ffffffff61087295819a957fc4399022965bad9b2b468bbd8c758a7e80cdde36ff3088ddbb7f93bdfb5623cb9f9e9d99946119928761044e9f9b986005936119f69f9a600092611a355750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b9101555b3360005260026020526119ad836040600020612fda565b501660005260036020526119c5816040600020612fda565b508d82611a0c575b5050506108646040519a8b9a6119e58c6064356120d5565b60a060208d015260a08c01916128fb565b97838903608085015216963396602435966128fb565b611a2c92611a1a9133612a88565b60005260056020526040600020612fda565b508c8f8d6119cd565b01519050388061091d565b906005840160005260206000209160005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085168110611b3057506108729563ffffffff9a957fc4399022965bad9b2b468bbd8c758a7e80cdde36ff3088ddbb7f93bdfb5623cb9f9e9d999460018761044e9f9b96928f96936119f69f9a94837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06005971610611af9575b505050811b01910155611996565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c19169055388080611aeb565b939550918194969750600160209291839285015181550194019201918f9492918f97969492611a51565b906004860160005260206000209160005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085168110611c0f5750918391600193837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060e098971610611bd8575b505050811b0160048501556118d4565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558f8080611bc8565b91926020600181928685015181550194019201611b6b565b015190508f8061091d565b9190600386016000526020600020906000935b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084168510611ce35760019450837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610611cac575b505050811b01600384015561184c565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558e8080611c9c565b81810151835560209485019460019093019290910190611c45565b9190600286016000526020600020906000935b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084168510611daf5760019450837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610611d78575b505050811b0160028401556117c8565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558e8080611d68565b81810151835560209485019460019093019290910190611d11565b60046040517fa0677dd0000000000000000000000000000000000000000000000000000000008152fd5b604485604051907f36a7c503000000000000000000000000000000000000000000000000000000008252600482015260406024820152fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457611e63612bc7565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600a541617600a55337f2789711f6fd67d131ad68378617b5d1d21a2c92b34d7c3745d70b3957c08096c600080a2005b34610144576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760043567ffffffffffffffff811161014457611f069036906004016122c4565b60ff600a54166104ac57611f1a9133612a88565b90816000526005602052604060002091825491821561066e5760005b838110611f3f57005b80611f4c60019287612eb7565b90549060031b1c60005260048352604060002063ffffffff8382015460a01c1660005260098452604060002054151580611fd6575b611f8d575b5001611f36565b7f95d94f817db4971aa99ba35d0fe019bd8cc39866fbe02b6d47b5f0f3727fb67360405186815260408682015280611fcd339460026040840191016125d0565b0390a286611f86565b50611fee336000526007602052604060002054151590565b611f81565b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457604051604081019080821067ffffffffffffffff831117610aa75761066a91604052601a81527f576f726b666c6f77526567697374727920312e302e302d64657600000000000060208201526040519182916020835260208301906120e2565b346101445760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760043563ffffffff8116810361014457610e8f61066a916044359060243590612743565b90600282101561047d5752565b919082519283825260005b84811061212c5750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b6020818301810151848301820152016120ed565b6121e19160e06121d06121be6121ac6101008651865273ffffffffffffffffffffffffffffffffffffffff602088015116602087015263ffffffff6040880151166040870152612198606088015160608801906120d5565b6080870151908060808801528601906120e2565b60a086015185820360a08701526120e2565b60c085015184820360c08601526120e2565b9201519060e08184039101526120e2565b90565b6020808201906020835283518092526040830192602060408460051b8301019501936000915b84831061221a5750505050505090565b9091929394958480612256837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc086600196030187528a51612140565b980193019301919493929061220a565b610100810190811067ffffffffffffffff821117610aa757604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610aa757604052565b9181601f840112156101445782359167ffffffffffffffff8311610144576020838186019501011161014457565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126101445760043567ffffffffffffffff9283821161014457806023830112156101445781600401359384116101445760248460051b8301011161014457602401919060243580151581036101445790565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361014457565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126101445760043573ffffffffffffffffffffffffffffffffffffffff8116810361014457916024359067ffffffffffffffff8211610144576123f8916004016122c4565b9091565b67ffffffffffffffff8111610aa75760051b60200190565b6040519061242182612266565b606060e0836000815260006020820152600060408201526000838201528260808201528260a08201528260c08201520152565b6040516020810181811067ffffffffffffffff821117610aa7576040526000815290565b90612482826123fc565b61248f6040519182612283565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06124bd82946123fc565b019060005b8281106124ce57505050565b6020906124d9612414565b828285010152016124c2565b919082018092116124f257565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116124f257565b80518210156125425760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600282101561047d5752565b90600182811c921680156125c6575b602083101461259757565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f169161258c565b8054600093926125df8261257d565b918282526020936001916001811690816000146126475750600114612606575b5050505050565b90939495506000929192528360002092846000945b838610612633575050505001019038808080806125ff565b80548587018301529401938590820161261b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168685015250505090151560051b0101915038808080806125ff565b90600560e060409361273f85519161269b83612266565b6127388397825485526126e560ff600185015473ffffffffffffffffffffffffffffffffffffffff8116602089015263ffffffff8160a01c168489015260c01c1660608701612571565b80516126f88161078d81600288016125d0565b608086015280516127108161078d81600388016125d0565b60a086015280516127288161078d81600488016125d0565b60c08601525180968193016125d0565b0384612283565b0152565b63ffffffff16916000838152600360209060036020526040936040842054908187101561282857612797918160648993118015612820575b612818575b8161278b82856124e5565b11156128085750612521565b946127a186612478565b96845b8781106127b657505050505050505090565b6001908287528486526127d58888206127cf83876124e5565b90612eb7565b905490861b1c8752600486526127ec888820612684565b6127f6828c61252e565b52612801818b61252e565b50016127a4565b6128139150826124e5565b612521565b506064612780565b50801561277b565b50505050505050506121e1612454565b92919267ffffffffffffffff8211610aa7576040519161288060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184612283565b829481845281830111610144578281602093846000960137010152565b8181106128a8575050565b6000815560010161289d565b9190601f81116128c357505050565b6128ef926000526020600020906020601f840160051c830193106128f1575b601f0160051c019061289d565b565b90915081906128e2565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b91907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009060601b1682526014906000928154926129768461257d565b926001946001811690816000146129dd5750600114612998575b505050505090565b9091929395945060005260209460206000206000905b8582106129ca5750505050601492935001013880808080612990565b80548583018501529087019082016129ae565b92505050601494507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091935016838301528015150201013880808080612990565b612a28815461257d565b9081612a32575050565b81601f60009311600114612a44575055565b908083918252612a63601f60208420940160051c84016001850161289d565b5555565b91908110156125425760051b0190565b3563ffffffff811681036101445790565b91906034612add91836040519485927fffffffffffffffffffffffffffffffffffffffff000000000000000000000000602085019860601b168852848401378101600083820152036014810184520182612283565b51902090565b73ffffffffffffffffffffffffffffffffffffffff1691600083815260029260209060026020526040936040842054908183101561282857612b3a91816064859311801561282057612818578161278b82856124e5565b94612b4486612478565b96845b878110612b5957505050505050505090565b600190828752838652612b728888206127cf83886124e5565b90549060031b1c875260048652612b8a888820612684565b612b94828c61252e565b52612b9f818b61252e565b5001612b47565b3573ffffffffffffffffffffffffffffffffffffffff811681036101445790565b73ffffffffffffffffffffffffffffffffffffffff600154163303612be857565b60046040517f2b5c74de000000000000000000000000000000000000000000000000000000008152fd5b63ffffffff1680600052600960205260406000205415612c8b575073ffffffffffffffffffffffffffffffffffffffff1680600052600760205260406000205415612c5a5750565b602490604051907f85982a000000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907f8fe6d7e10000000000000000000000000000000000000000000000000000000082526004820152fd5b91909115612d835760c891828111612d4d5750818111612d185750808211612ce2575050565b60449250604051917ecd56a800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b604491604051917ecd56a800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b60449083604051917ecd56a800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b60046040517f7dc2f4e1000000000000000000000000000000000000000000000000000000008152fd5b90600052600460205260406000209073ffffffffffffffffffffffffffffffffffffffff8060018401541691821561066e5716809103612deb575090565b602490604051907f31ee6dc70000000000000000000000000000000000000000000000000000000082526004820152fd5b9081518151908181149384612e33575b5050505090565b6020929394508201209201201438808080612e2c565b6008548110156125425760086000527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30190600090565b6006548110156125425760066000527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600090565b80548210156125425760005260206000200190600090565b600081815260096020526040812054612f835760085468010000000000000000811015612f56579082612f42612f0d84600160409601600855612e49565b81939154907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9060031b92831b921b19161790565b905560085492815260096020522055600190565b6024827f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b905090565b600081815260076020526040812054612f835760065468010000000000000000811015612f56579082612fc6612f0d84600160409601600655612e80565b905560065492815260076020522055600190565b9190600183016000908282528060205260408220541560001461306057845494680100000000000000008610156130335783613023612f0d886001604098999a01855584612eb7565b9055549382526020522055600190565b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b50925050565b60008181526009602052604081205490919080156131b4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90818101818111613187576008549083820191821161315a57818103613126575b50505060085480156130f9578101906130d882612e49565b909182549160031b1b19169055600855815260096020526040812055600190565b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526031600452fd5b613144613135612f0d93612e49565b90549060031b1c928392612e49565b90558452600960205260408420553880806130c0565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b505090565b60008181526007602052604081205490919080156131b4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90818101818111613187576006549083820191821161315a5781810361324c575b50505060065480156130f95781019061322b82612e80565b909182549160031b1b19169055600655815260076020526040812055600190565b61326a61325b612f0d93612e80565b90549060031b1c928392612e80565b9055845260076020526040842055388080613213565b90600182019060009281845282602052604084205490811515600014612e2c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff918281018181116133a55782549084820191821161337857818103613343575b50505080548015613316578201916132f98383612eb7565b909182549160031b1b191690555582526020526040812055600190565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526031600452fd5b613363613353612f0d9386612eb7565b90549060031b1c92839286612eb7565b905586528460205260408620553880806132e1565b6024887f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AddressNotAuthorized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerIsNotWorkflowOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotTransferToSelf\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"}],\"name\":\"DONNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWorkflowID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnerCannotBeZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryLocked\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"providedLength\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"maxAllowedLength\",\"type\":\"uint8\"}],\"name\":\"URLTooLong\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowAlreadyInDesiredStatus\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowContentNotUpdated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowIDAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WorkflowIDNotUpdated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"providedLength\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"maxAllowedLength\",\"type\":\"uint8\"}],\"name\":\"WorkflowNameTooLong\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32[]\",\"name\":\"donIDs\",\"type\":\"uint32[]\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"AllowedDONsUpdatedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"AuthorizedAddressesUpdatedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"lockedBy\",\"type\":\"address\"}],\"name\":\"RegistryLockedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"unlockedBy\",\"type\":\"address\"}],\"name\":\"RegistryUnlockedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"WorkflowActivatedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"WorkflowDeletedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"secretsURLHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"WorkflowForceUpdateSecretsRequestedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"WorkflowPausedV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"WorkflowRegisteredV1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"oldWorkflowID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newWorkflowID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"WorkflowUpdatedV1\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"workflowKey\",\"type\":\"bytes32\"}],\"name\":\"activateWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"field\",\"type\":\"string\"}],\"name\":\"computeHashKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"workflowKey\",\"type\":\"bytes32\"}],\"name\":\"deleteWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedDONs\",\"outputs\":[{\"internalType\":\"uint32[]\",\"name\":\"allowedDONs\",\"type\":\"uint32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedAddresses\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"authorizedAddresses\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"}],\"name\":\"getWorkflowMetadata\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"internalType\":\"structWorkflowRegistry.WorkflowMetadata\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"getWorkflowMetadataListByDON\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"internalType\":\"structWorkflowRegistry.WorkflowMetadata[]\",\"name\":\"workflowMetadataList\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"getWorkflowMetadataListByOwner\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"internalType\":\"structWorkflowRegistry.WorkflowMetadata[]\",\"name\":\"workflowMetadataList\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isRegistryLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lockRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"workflowKey\",\"type\":\"bytes32\"}],\"name\":\"pauseWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"workflowName\",\"type\":\"string\"},{\"internalType\":\"bytes32\",\"name\":\"workflowID\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"donID\",\"type\":\"uint32\"},{\"internalType\":\"enumWorkflowRegistry.WorkflowStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"registerWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"requestForceUpdateSecrets\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"donIDs\",\"type\":\"uint32[]\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"updateAllowedDONs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"updateAuthorizedAddresses\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"workflowKey\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"newWorkflowID\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"binaryURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"configURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"secretsURL\",\"type\":\"string\"}],\"name\":\"updateWorkflow\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6080806040523461004a57331561003b57600180546001600160a01b03191633179055600a805460ff191690556040516133f390816100508239f35b639b15e16f60e01b8152600490fd5b600080fdfe6080604052600436101561001257600080fd5b60003560e01c806308e7f63a14612096578063181f5a77146120075780632303348a14611eca5780632b596f6d14611e3c5780633ccd14ff14611502578063695e13401461135a5780636f35177114611281578063724c13dd1461118a5780637497066b1461106f57806379ba509714610f995780637ec0846d14610f0e5780638da5cb5b14610ebc5780639f4cb53414610e9b578063b87a019414610e45578063d4b89c7414610698578063db800092146105fd578063e3dce080146104d6578063e690f33214610362578063f2fde38b14610284578063f794bdeb146101495763f99ecb6b1461010357600080fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457602060ff600a54166040519015158152f35b600080fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610144576006805461018581612410565b6101926040519182612297565b81815261019e82612410565b916020937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060208401940136853760005b82811061023257505050906040519283926020840190602085525180915260408401929160005b82811061020557505050500390f35b835173ffffffffffffffffffffffffffffffffffffffff16855286955093810193928101926001016101f6565b6001908260005273ffffffffffffffffffffffffffffffffffffffff817ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01541661027d8287612542565b52016101cf565b346101445760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610144576102bb61237e565b6102c3612bdb565b73ffffffffffffffffffffffffffffffffffffffff8091169033821461033857817fffffffffffffffffffffffff00000000000000000000000000000000000000006000541617600055600154167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278600080a3005b60046040517fdad89dca000000000000000000000000000000000000000000000000000000008152fd5b346101445760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760ff600a54166104ac576103a760043533612dc1565b600181019081549160ff8360c01c16600281101561047d576001146104535778010000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff841617905580547f6a0ed88e9cf3cb493ab4028fcb1dc7d18f0130fcdfba096edde0aadbfbf5e99f63ffffffff604051946020865260a01c16938061044e339560026020840191016125e4565b0390a4005b60046040517f6f861db1000000000000000000000000000000000000000000000000000000008152fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60046040517f78a4e7d9000000000000000000000000000000000000000000000000000000008152fd5b34610144576104e436612306565b916104ed612bdb565b60ff600a54166104ac5760005b828110610589575060405191806040840160408552526060830191906000905b8082106105515785151560208601527f509460cccbb176edde6cac28895a4415a24961b8f3a0bd2617b9bb7b4e166c9b85850386a1005b90919283359073ffffffffffffffffffffffffffffffffffffffff82168092036101445760019181526020809101940192019061051a565b60019084156105cb576105c373ffffffffffffffffffffffffffffffffffffffff6105bd6105b8848888612a7b565b612bba565b16612f9c565b505b016104fa565b6105f773ffffffffffffffffffffffffffffffffffffffff6105f16105b8848888612a7b565b166131cd565b506105c5565b346101445761061d61060e366123a1565b91610617612428565b50612a9c565b6000526004602052604060002073ffffffffffffffffffffffffffffffffffffffff6001820154161561066e5761065661066a91612698565b604051918291602083526020830190612154565b0390f35b60046040517f871e01b2000000000000000000000000000000000000000000000000000000008152fd5b346101445760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760443567ffffffffffffffff8111610144576106e79036906004016122d8565b9060643567ffffffffffffffff8111610144576107089036906004016122d8565b9160843567ffffffffffffffff8111610144576107299036906004016122d8565b60ff600a94929454166104ac57610744818688602435612cd0565b61075060043533612dc1565b9163ffffffff600184015460a01c169561076a3388612c26565b8354946024358614610e1b576107a56040516107948161078d8160038b016125e4565b0382612297565b61079f368c8561284c565b90612e30565b6107c76040516107bc8161078d8160048c016125e4565b61079f36868861284c565b6107e96040516107de8161078d8160058d016125e4565b61079f36898d61284c565b918080610e14575b80610e0d575b610de357602435885515610c8e575b15610b3d575b15610890575b926108807f41161473ce2ed633d9f902aab9702d16a5531da27ec84e1939abeffe54ad7353959361044e93610872610864978d604051998a996024358b5260a060208c0152600260a08c0191016125e4565b9189830360408b015261290f565b91868303606088015261290f565b908382036080850152339761290f565b61089d6005860154612591565b610ad6575b67ffffffffffffffff8411610aa7576108cb846108c26005880154612591565b600588016128c8565b6000601f85116001146109a757928492610872610880938a9b9c61094f876108649b9a61044e9a7f41161473ce2ed633d9f902aab9702d16a5531da27ec84e1939abeffe54ad73539e9f60009261099c575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60058a01555b8c8780610972575b50509c9b9a9950935050929495509250610812565b61097c9133612a9c565b60005260056020526109946004356040600020612fee565b508c8761095d565b013590508f8061091d565b9860058601600052602060002060005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087168110610a8f5750926108726108809361044e969388968c7f41161473ce2ed633d9f902aab9702d16a5531da27ec84e1939abeffe54ad73539c9d9e9f897fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06108649e9d1610610a57575b505050600187811b0160058a0155610955565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88b60031b161c199101351690558e8d81610a44565b898c0135825560209b8c019b600190920191016109b7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516020810190610b1c81610af060058a01338661294e565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612297565b5190206000526005602052610b376004356040600020613294565b506108a2565b67ffffffffffffffff8311610aa757610b6683610b5d6004890154612591565b600489016128c8565b600083601f8111600114610bc75780610bb292600091610bbc575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b600487015561080c565b90508601358d610b81565b506004870160005260206000209060005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086168110610c765750847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610610c3e575b5050600183811b01600487015561080c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c19908601351690558a80610c2c565b9091602060018192858a013581550193019101610bd8565b67ffffffffffffffff8b11610aa757610cb78b610cae60038a0154612591565b60038a016128c8565b60008b601f8111600114610d175780610d0292600091610d0c57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b6003880155610806565b90508501358e610b81565b506003880160005260206000209060005b8d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081168210610dca578091507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610610d91575b905060018092501b016003880155610806565b60f87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9160031b161c19908501351690558b808c610d7e565b5085820135835560019092019160209182019101610d28565b60046040517f6b4a810d000000000000000000000000000000000000000000000000000000008152fd5b50826107f7565b50816107f1565b60046040517f95406722000000000000000000000000000000000000000000000000000000008152fd5b346101445760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445761066a610e8f610e8261237e565b6044359060243590612af7565b604051918291826121f8565b34610144576020610eb4610eae366123a1565b91612a9c565b604051908152f35b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457610f45612bdb565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600a5416600a557f11a03e25ee25bf1459f9e1cb293ea03707d84917f54a65e32c9a7be2f2edd68a6020604051338152a1005b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760005473ffffffffffffffffffffffffffffffffffffffff808216330361104557600154917fffffffffffffffffffffffff0000000000000000000000000000000000000000903382851617600155166000553391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60046040517f02b543c6000000000000000000000000000000000000000000000000000000008152fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457600880546110ab81612410565b6110b86040519182612297565b8181526110c482612410565b916020937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060208401940136853760005b82811061114857505050906040519283926020840190602085525180915260408401929160005b82811061112b57505050500390f35b835163ffffffff168552869550938101939281019260010161111c565b6001908260005263ffffffff817ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30154166111838287612542565b52016110f5565b346101445761119836612306565b916111a1612bdb565b60ff600a54166104ac5760005b82811061122d575060405191806040840160408552526060830191906000905b8082106112055785151560208601527fcab63bf31d1e656baa23cebef64e12033ea0ffbd44b1278c3747beec2d2f618c85850386a1005b90919283359063ffffffff8216809203610144576001918152602080910194019201906111ce565b600190841561125f5761125763ffffffff61125161124c848888612a7b565b612a8b565b16612ee3565b505b016111ae565b61127b63ffffffff61127561124c848888612a7b565b1661307a565b50611259565b346101445760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760ff600a54166104ac576112c660043533612dc1565b600181019081549163ffffffff8360a01c169260ff8160c01c16600281101561047d5715610453577fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff9061131a3386612c26565b16905580547f17b2d730bb5e064df3fbc6165c8aceb3b0d62c524c196c0bc1012209280bc9a6604051602081528061044e339560026020840191016125e4565b34610144576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610144576004359060ff600a54166104ac576113a28233612dc1565b916113ba336000526007602052604060002054151590565b156114d25760049233600052600283526113d8826040600020613294565b50600181019063ffffffff80835460a01c16600052600385526113ff846040600020613294565b506005820161140e8154612591565b61149e575b508154925460a01c16917f76ee2dfcae10cb8522e62e713e62660e09ecfaab08db15d9404de1914132257160405186815280611456339560028a840191016125e4565b0390a46000525261149c60056040600020600081556000600182015561147e60028201612a32565b61148a60038201612a32565b61149660048201612a32565b01612a32565b005b6040516114b381610af089820194338661294e565b519020600052600585526114cb846040600020613294565b5086611413565b60246040517f85982a00000000000000000000000000000000000000000000000000000000008152336004820152fd5b346101445760e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760043567ffffffffffffffff8111610144576115519036906004016122d8565b6044359163ffffffff8316830361014457600260643510156101445760843567ffffffffffffffff81116101445761158d9036906004016122d8565b91909260a43567ffffffffffffffff8111610144576115b09036906004016122d8565b60c43567ffffffffffffffff8111610144576115d09036906004016122d8565b96909560ff600a54166104ac576115e7338a612c26565b60408511611e04576115fd888483602435612cd0565b611608858733612a9c565b80600052600460205273ffffffffffffffffffffffffffffffffffffffff60016040600020015416611dda57604051906116418261227a565b602435825233602083015263ffffffff8b16604083015261166760643560608401612585565b61167236888a61284c565b608083015261168236848661284c565b60a083015261169236868861284c565b60c08301526116a2368b8b61284c565b60e0830152806000526004602052604060002091805183556001830173ffffffffffffffffffffffffffffffffffffffff60208301511681549077ffffffff0000000000000000000000000000000000000000604085015160a01b16906060850151600281101561047d5778ff0000000000000000000000000000000000000000000000007fffffffffffffff000000000000000000000000000000000000000000000000009160c01b1693161717179055608081015180519067ffffffffffffffff8211610aa7576117858261177c6002880154612591565b600288016128c8565b602090601f8311600114611d0e576117d2929160009183611c375750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60028401555b60a081015180519067ffffffffffffffff8211610aa757611809826118006003880154612591565b600388016128c8565b602090601f8311600114611c4257611856929160009183611c375750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60038401555b60c081015180519067ffffffffffffffff8211610aa75761188d826118846004880154612591565b600488016128c8565b602090601f8311600114611b6a5791806118de9260e09594600092611a455750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b60048501555b015180519267ffffffffffffffff8411610aa757838d926119168e9661190d6005860154612591565b600586016128c8565b602090601f8311600114611a50579463ffffffff61087295819a957fc4399022965bad9b2b468bbd8c758a7e80cdde36ff3088ddbb7f93bdfb5623cb9f9e9d99946119a28761044e9f9b98600593611a069f9a600092611a455750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b9101555b3360005260026020526119bd836040600020612fee565b501660005260036020526119d5816040600020612fee565b508d82611a1c575b5050506108646040519a8b9a6119f58c6064356120e9565b60a060208d015260a08c019161290f565b978389036080850152169633966024359661290f565b611a3c92611a2a9133612a9c565b60005260056020526040600020612fee565b508c8f8d6119dd565b01519050388061091d565b906005840160005260206000209160005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085168110611b4057506108729563ffffffff9a957fc4399022965bad9b2b468bbd8c758a7e80cdde36ff3088ddbb7f93bdfb5623cb9f9e9d999460018761044e9f9b96928f9693611a069f9a94837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06005971610611b09575b505050811b019101556119a6565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c19169055388080611afb565b939550918194969750600160209291839285015181550194019201918f9492918f97969492611a61565b906004860160005260206000209160005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe085168110611c1f5750918391600193837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe060e098971610611be8575b505050811b0160048501556118e4565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558f8080611bd8565b91926020600181928685015181550194019201611b7b565b015190508f8061091d565b9190600386016000526020600020906000935b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084168510611cf35760019450837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610611cbc575b505050811b01600384015561185c565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558e8080611cac565b81810151835560209485019460019093019290910190611c55565b9190600286016000526020600020906000935b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084168510611dbf5760019450837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0811610611d88575b505050811b0160028401556117d8565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558e8080611d78565b81810151835560209485019460019093019290910190611d21565b60046040517fa0677dd0000000000000000000000000000000000000000000000000000000008152fd5b604485604051907f36a7c503000000000000000000000000000000000000000000000000000000008252600482015260406024820152fd5b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457611e73612bdb565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600a541617600a557f2789711f6fd67d131ad68378617b5d1d21a2c92b34d7c3745d70b3957c08096c6020604051338152a1005b34610144576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760043567ffffffffffffffff811161014457611f1a9036906004016122d8565b60ff600a54166104ac57611f2e9133612a9c565b90816000526005602052604060002091825491821561066e5760005b838110611f5357005b80611f6060019287612ecb565b90549060031b1c60005260048352604060002063ffffffff8382015460a01c1660005260098452604060002054151580611fea575b611fa1575b5001611f4a565b7f95d94f817db4971aa99ba35d0fe019bd8cc39866fbe02b6d47b5f0f3727fb67360405186815260408682015280611fe1339460026040840191016125e4565b0390a286611f9a565b50612002336000526007602052604060002054151590565b611f95565b346101445760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014457604051604081019080821067ffffffffffffffff831117610aa75761066a91604052601a81527f576f726b666c6f77526567697374727920312e302e302d64657600000000000060208201526040519182916020835260208301906120f6565b346101445760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101445760043563ffffffff8116810361014457610e8f61066a916044359060243590612757565b90600282101561047d5752565b919082519283825260005b8481106121405750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b602081830181015184830182015201612101565b6121f59160e06121e46121d26121c06101008651865273ffffffffffffffffffffffffffffffffffffffff602088015116602087015263ffffffff60408801511660408701526121ac606088015160608801906120e9565b6080870151908060808801528601906120f6565b60a086015185820360a08701526120f6565b60c085015184820360c08601526120f6565b9201519060e08184039101526120f6565b90565b6020808201906020835283518092526040830192602060408460051b8301019501936000915b84831061222e5750505050505090565b909192939495848061226a837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc086600196030187528a51612154565b980193019301919493929061221e565b610100810190811067ffffffffffffffff821117610aa757604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610aa757604052565b9181601f840112156101445782359167ffffffffffffffff8311610144576020838186019501011161014457565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126101445760043567ffffffffffffffff9283821161014457806023830112156101445781600401359384116101445760248460051b8301011161014457602401919060243580151581036101445790565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361014457565b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126101445760043573ffffffffffffffffffffffffffffffffffffffff8116810361014457916024359067ffffffffffffffff82116101445761240c916004016122d8565b9091565b67ffffffffffffffff8111610aa75760051b60200190565b604051906124358261227a565b606060e0836000815260006020820152600060408201526000838201528260808201528260a08201528260c08201520152565b6040516020810181811067ffffffffffffffff821117610aa7576040526000815290565b9061249682612410565b6124a36040519182612297565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06124d18294612410565b019060005b8281106124e257505050565b6020906124ed612428565b828285010152016124d6565b9190820180921161250657565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9190820391821161250657565b80518210156125565760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600282101561047d5752565b90600182811c921680156125da575b60208310146125ab57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f16916125a0565b8054600093926125f382612591565b9182825260209360019160018116908160001461265b575060011461261a575b5050505050565b90939495506000929192528360002092846000945b83861061264757505050500101903880808080612613565b80548587018301529401938590820161262f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168685015250505090151560051b010191503880808080612613565b90600560e06040936127538551916126af8361227a565b61274c8397825485526126f960ff600185015473ffffffffffffffffffffffffffffffffffffffff8116602089015263ffffffff8160a01c168489015260c01c1660608701612585565b805161270c8161078d81600288016125e4565b608086015280516127248161078d81600388016125e4565b60a0860152805161273c8161078d81600488016125e4565b60c08601525180968193016125e4565b0384612297565b0152565b63ffffffff16916000838152600360209060036020526040936040842054908187101561283c576127ab918160648993118015612834575b61282c575b8161279f82856124f9565b111561281c5750612535565b946127b58661248c565b96845b8781106127ca57505050505050505090565b6001908287528486526127e98888206127e383876124f9565b90612ecb565b905490861b1c875260048652612800888820612698565b61280a828c612542565b52612815818b612542565b50016127b8565b6128279150826124f9565b612535565b506064612794565b50801561278f565b50505050505050506121f5612468565b92919267ffffffffffffffff8211610aa7576040519161289460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184612297565b829481845281830111610144578281602093846000960137010152565b8181106128bc575050565b600081556001016128b1565b9190601f81116128d757505050565b612903926000526020600020906020601f840160051c83019310612905575b601f0160051c01906128b1565b565b90915081906128f6565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b91907fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009060601b16825260149060009281549261298a84612591565b926001946001811690816000146129f157506001146129ac575b505050505090565b9091929395945060005260209460206000206000905b8582106129de57505050506014929350010138808080806129a4565b80548583018501529087019082016129c2565b92505050601494507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00919350168383015280151502010138808080806129a4565b612a3c8154612591565b9081612a46575050565b81601f60009311600114612a58575055565b908083918252612a77601f60208420940160051c8401600185016128b1565b5555565b91908110156125565760051b0190565b3563ffffffff811681036101445790565b91906034612af191836040519485927fffffffffffffffffffffffffffffffffffffffff000000000000000000000000602085019860601b168852848401378101600083820152036014810184520182612297565b51902090565b73ffffffffffffffffffffffffffffffffffffffff1691600083815260029260209060026020526040936040842054908183101561283c57612b4e9181606485931180156128345761282c578161279f82856124f9565b94612b588661248c565b96845b878110612b6d57505050505050505090565b600190828752838652612b868888206127e383886124f9565b90549060031b1c875260048652612b9e888820612698565b612ba8828c612542565b52612bb3818b612542565b5001612b5b565b3573ffffffffffffffffffffffffffffffffffffffff811681036101445790565b73ffffffffffffffffffffffffffffffffffffffff600154163303612bfc57565b60046040517f2b5c74de000000000000000000000000000000000000000000000000000000008152fd5b63ffffffff1680600052600960205260406000205415612c9f575073ffffffffffffffffffffffffffffffffffffffff1680600052600760205260406000205415612c6e5750565b602490604051907f85982a000000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907f8fe6d7e10000000000000000000000000000000000000000000000000000000082526004820152fd5b91909115612d975760c891828111612d615750818111612d2c5750808211612cf6575050565b60449250604051917ecd56a800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b604491604051917ecd56a800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b60449083604051917ecd56a800000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b60046040517f7dc2f4e1000000000000000000000000000000000000000000000000000000008152fd5b90600052600460205260406000209073ffffffffffffffffffffffffffffffffffffffff8060018401541691821561066e5716809103612dff575090565b602490604051907f31ee6dc70000000000000000000000000000000000000000000000000000000082526004820152fd5b9081518151908181149384612e47575b5050505090565b6020929394508201209201201438808080612e40565b6008548110156125565760086000527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30190600090565b6006548110156125565760066000527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600090565b80548210156125565760005260206000200190600090565b600081815260096020526040812054612f975760085468010000000000000000811015612f6a579082612f56612f2184600160409601600855612e5d565b81939154907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9060031b92831b921b19161790565b905560085492815260096020522055600190565b6024827f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b905090565b600081815260076020526040812054612f975760065468010000000000000000811015612f6a579082612fda612f2184600160409601600655612e94565b905560065492815260076020522055600190565b9190600183016000908282528060205260408220541560001461307457845494680100000000000000008610156130475783613037612f21886001604098999a01855584612ecb565b9055549382526020522055600190565b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b50925050565b60008181526009602052604081205490919080156131c8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081810181811161319b576008549083820191821161316e5781810361313a575b505050600854801561310d578101906130ec82612e5d565b909182549160031b1b19169055600855815260096020526040812055600190565b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526031600452fd5b613158613149612f2193612e5d565b90549060031b1c928392612e5d565b90558452600960205260408420553880806130d4565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b505090565b60008181526007602052604081205490919080156131c8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081810181811161319b576006549083820191821161316e57818103613260575b505050600654801561310d5781019061323f82612e94565b909182549160031b1b19169055600655815260076020526040812055600190565b61327e61326f612f2193612e94565b90549060031b1c928392612e94565b9055845260076020526040842055388080613227565b90600182019060009281845282602052604084205490811515600014612e40577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff918281018181116133b95782549084820191821161338c57818103613357575b5050508054801561332a5782019161330d8383612ecb565b909182549160031b1b191690555582526020526040812055600190565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526031600452fd5b613377613367612f219386612ecb565b90549060031b1c92839286612ecb565b905586528460205260408620553880806132f5565b6024887f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fdfea164736f6c6343000818000a", } var WorkflowRegistryABI = WorkflowRegistryMetaData.ABI @@ -1097,28 +1097,18 @@ type WorkflowRegistryRegistryLockedV1 struct { Raw types.Log } -func (_WorkflowRegistry *WorkflowRegistryFilterer) FilterRegistryLockedV1(opts *bind.FilterOpts, lockedBy []common.Address) (*WorkflowRegistryRegistryLockedV1Iterator, error) { +func (_WorkflowRegistry *WorkflowRegistryFilterer) FilterRegistryLockedV1(opts *bind.FilterOpts) (*WorkflowRegistryRegistryLockedV1Iterator, error) { - var lockedByRule []interface{} - for _, lockedByItem := range lockedBy { - lockedByRule = append(lockedByRule, lockedByItem) - } - - logs, sub, err := _WorkflowRegistry.contract.FilterLogs(opts, "RegistryLockedV1", lockedByRule) + logs, sub, err := _WorkflowRegistry.contract.FilterLogs(opts, "RegistryLockedV1") if err != nil { return nil, err } return &WorkflowRegistryRegistryLockedV1Iterator{contract: _WorkflowRegistry.contract, event: "RegistryLockedV1", logs: logs, sub: sub}, nil } -func (_WorkflowRegistry *WorkflowRegistryFilterer) WatchRegistryLockedV1(opts *bind.WatchOpts, sink chan<- *WorkflowRegistryRegistryLockedV1, lockedBy []common.Address) (event.Subscription, error) { - - var lockedByRule []interface{} - for _, lockedByItem := range lockedBy { - lockedByRule = append(lockedByRule, lockedByItem) - } +func (_WorkflowRegistry *WorkflowRegistryFilterer) WatchRegistryLockedV1(opts *bind.WatchOpts, sink chan<- *WorkflowRegistryRegistryLockedV1) (event.Subscription, error) { - logs, sub, err := _WorkflowRegistry.contract.WatchLogs(opts, "RegistryLockedV1", lockedByRule) + logs, sub, err := _WorkflowRegistry.contract.WatchLogs(opts, "RegistryLockedV1") if err != nil { return nil, err } @@ -1224,28 +1214,18 @@ type WorkflowRegistryRegistryUnlockedV1 struct { Raw types.Log } -func (_WorkflowRegistry *WorkflowRegistryFilterer) FilterRegistryUnlockedV1(opts *bind.FilterOpts, unlockedBy []common.Address) (*WorkflowRegistryRegistryUnlockedV1Iterator, error) { +func (_WorkflowRegistry *WorkflowRegistryFilterer) FilterRegistryUnlockedV1(opts *bind.FilterOpts) (*WorkflowRegistryRegistryUnlockedV1Iterator, error) { - var unlockedByRule []interface{} - for _, unlockedByItem := range unlockedBy { - unlockedByRule = append(unlockedByRule, unlockedByItem) - } - - logs, sub, err := _WorkflowRegistry.contract.FilterLogs(opts, "RegistryUnlockedV1", unlockedByRule) + logs, sub, err := _WorkflowRegistry.contract.FilterLogs(opts, "RegistryUnlockedV1") if err != nil { return nil, err } return &WorkflowRegistryRegistryUnlockedV1Iterator{contract: _WorkflowRegistry.contract, event: "RegistryUnlockedV1", logs: logs, sub: sub}, nil } -func (_WorkflowRegistry *WorkflowRegistryFilterer) WatchRegistryUnlockedV1(opts *bind.WatchOpts, sink chan<- *WorkflowRegistryRegistryUnlockedV1, unlockedBy []common.Address) (event.Subscription, error) { - - var unlockedByRule []interface{} - for _, unlockedByItem := range unlockedBy { - unlockedByRule = append(unlockedByRule, unlockedByItem) - } +func (_WorkflowRegistry *WorkflowRegistryFilterer) WatchRegistryUnlockedV1(opts *bind.WatchOpts, sink chan<- *WorkflowRegistryRegistryUnlockedV1) (event.Subscription, error) { - logs, sub, err := _WorkflowRegistry.contract.WatchLogs(opts, "RegistryUnlockedV1", unlockedByRule) + logs, sub, err := _WorkflowRegistry.contract.WatchLogs(opts, "RegistryUnlockedV1") if err != nil { return nil, err } @@ -2304,15 +2284,15 @@ type WorkflowRegistryInterface interface { ParseOwnershipTransferred(log types.Log) (*WorkflowRegistryOwnershipTransferred, error) - FilterRegistryLockedV1(opts *bind.FilterOpts, lockedBy []common.Address) (*WorkflowRegistryRegistryLockedV1Iterator, error) + FilterRegistryLockedV1(opts *bind.FilterOpts) (*WorkflowRegistryRegistryLockedV1Iterator, error) - WatchRegistryLockedV1(opts *bind.WatchOpts, sink chan<- *WorkflowRegistryRegistryLockedV1, lockedBy []common.Address) (event.Subscription, error) + WatchRegistryLockedV1(opts *bind.WatchOpts, sink chan<- *WorkflowRegistryRegistryLockedV1) (event.Subscription, error) ParseRegistryLockedV1(log types.Log) (*WorkflowRegistryRegistryLockedV1, error) - FilterRegistryUnlockedV1(opts *bind.FilterOpts, unlockedBy []common.Address) (*WorkflowRegistryRegistryUnlockedV1Iterator, error) + FilterRegistryUnlockedV1(opts *bind.FilterOpts) (*WorkflowRegistryRegistryUnlockedV1Iterator, error) - WatchRegistryUnlockedV1(opts *bind.WatchOpts, sink chan<- *WorkflowRegistryRegistryUnlockedV1, unlockedBy []common.Address) (event.Subscription, error) + WatchRegistryUnlockedV1(opts *bind.WatchOpts, sink chan<- *WorkflowRegistryRegistryUnlockedV1) (event.Subscription, error) ParseRegistryUnlockedV1(log types.Log) (*WorkflowRegistryRegistryUnlockedV1, error) diff --git a/core/gethwrappers/workflow/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/workflow/generation/generated-wrapper-dependency-versions-do-not-edit.txt index b937cc957a6..7552f72d164 100644 --- a/core/gethwrappers/workflow/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/workflow/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,2 +1,2 @@ GETH_VERSION: 1.14.11 -workflow_registry_wrapper: ../../../contracts/solc/v0.8.24/WorkflowRegistry/WorkflowRegistry.abi ../../../contracts/solc/v0.8.24/WorkflowRegistry/WorkflowRegistry.bin 2f7e6d51370fbb3a6c467515127333b6cb4b998c61f2e0b74d5e07ccb1a8716b +workflow_registry_wrapper: ../../../contracts/solc/v0.8.24/WorkflowRegistry/WorkflowRegistry.abi ../../../contracts/solc/v0.8.24/WorkflowRegistry/WorkflowRegistry.bin 910925e0786fbe9efb686646ede620e7fc0536c74acdaeef49e96ac67580ea14 diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 29515df7034..554b11b5aa8 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -29,6 +29,7 @@ import ( "github.com/jmoiron/sqlx" "github.com/manyminds/api2go/jsonapi" "github.com/onsi/gomega" + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -406,6 +407,7 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn Logger: lggr, LoopRegistry: loopRegistry, GRPCOpts: loop.GRPCOpts{}, + Registerer: prometheus.NewRegistry(), // Don't use global registry here since otherwise multiple apps can create name conflicts. Could also potentially give a mock registry to test prometheus. MercuryPool: mercuryPool, CapabilitiesRegistry: capabilitiesRegistry, HTTPClient: c, diff --git a/core/internal/cltest/mocks.go b/core/internal/cltest/mocks.go index b8bb4657056..17c79f00831 100644 --- a/core/internal/cltest/mocks.go +++ b/core/internal/cltest/mocks.go @@ -11,6 +11,7 @@ import ( "time" "github.com/jmoiron/sqlx" + "github.com/prometheus/client_golang/prometheus" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" @@ -87,7 +88,7 @@ type InstanceAppFactoryWithKeystoreMock struct { } // NewApplication creates a new application with specified config and calls the authenticate function of the keystore -func (f InstanceAppFactoryWithKeystoreMock) NewApplication(ctx context.Context, cfg chainlink.GeneralConfig, lggr logger.Logger, db *sqlx.DB, ks cmd.TerminalKeyStoreAuthenticator) (chainlink.Application, error) { +func (f InstanceAppFactoryWithKeystoreMock) NewApplication(ctx context.Context, cfg chainlink.GeneralConfig, lggr logger.Logger, registerer prometheus.Registerer, db *sqlx.DB, ks cmd.TerminalKeyStoreAuthenticator) (chainlink.Application, error) { keyStore := f.App.GetKeyStore() err := ks.Authenticate(ctx, keyStore, cfg.Password()) if err != nil { @@ -102,7 +103,7 @@ type InstanceAppFactory struct { } // NewApplication creates a new application with specified config -func (f InstanceAppFactory) NewApplication(context.Context, chainlink.GeneralConfig, logger.Logger, *sqlx.DB, cmd.TerminalKeyStoreAuthenticator) (chainlink.Application, error) { +func (f InstanceAppFactory) NewApplication(context.Context, chainlink.GeneralConfig, logger.Logger, prometheus.Registerer, *sqlx.DB, cmd.TerminalKeyStoreAuthenticator) (chainlink.Application, error) { return f.App, nil } @@ -110,7 +111,7 @@ type seededAppFactory struct { Application chainlink.Application } -func (s seededAppFactory) NewApplication(context.Context, chainlink.GeneralConfig, logger.Logger, *sqlx.DB, cmd.TerminalKeyStoreAuthenticator) (chainlink.Application, error) { +func (s seededAppFactory) NewApplication(context.Context, chainlink.GeneralConfig, logger.Logger, prometheus.Registerer, *sqlx.DB, cmd.TerminalKeyStoreAuthenticator) (chainlink.Application, error) { return noopStopApplication{s.Application}, nil } diff --git a/core/internal/features/ocr2/features_ocr2_test.go b/core/internal/features/ocr2/features_ocr2_test.go index 7e443d59014..c8f49ac9328 100644 --- a/core/internal/features/ocr2/features_ocr2_test.go +++ b/core/internal/features/ocr2/features_ocr2_test.go @@ -738,14 +738,6 @@ func TestIntegration_OCR2_ForwarderFlow(t *testing.T) { }) } - tick := time.NewTicker(1 * time.Second) - defer tick.Stop() - go func() { - for range tick.C { - b.Commit() - } - }() - blockBeforeConfig := initOCR2(t, lggr, b, ocrContract, owner, bootstrapNode, oracles, forwarderContracts, transmitters, func(int64) string { return fmt.Sprintf(` type = "bootstrap" @@ -759,6 +751,14 @@ chainID = 1337 `, ocrContractAddress) }) + tick := time.NewTicker(1 * time.Second) + defer tick.Stop() + go func() { + for range tick.C { + b.Commit() + } + }() + var jids []int32 var servers, slowServers = make([]*httptest.Server, 4), make([]*httptest.Server, 4) // We expect metadata of: diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 731ab9daeaf..a8b218eef19 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -24,7 +24,7 @@ require ( github.com/prometheus/client_golang v1.20.5 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v0.8.1 - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d github.com/smartcontractkit/chainlink/deployment v0.0.0-00010101000000-000000000000 github.com/smartcontractkit/chainlink/v2 v2.14.0-mercury-20240807.0.20241106193309-5560cd76211a github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 @@ -296,7 +296,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 // indirect - github.com/smartcontractkit/chain-selectors v1.0.30 // indirect + github.com/smartcontractkit/chain-selectors v1.0.31 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241114154055-8d29ea018b57 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index e6fdeff1ef4..8f55042d16a 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1088,14 +1088,14 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 h1:qQH6fZZe31nBAG6INHph3z5ysDTPptyu0TR9uoJ1+ok= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86/go.mod h1:WtWOoVQQEHxRHL2hNmuRrvDfYfQG/CioFNoa9Rr2mBE= -github.com/smartcontractkit/chain-selectors v1.0.30 h1:jk+xVRocgQ/uvKLSd1JzeHJ/v+EKu1BjrreaSGqKzjo= -github.com/smartcontractkit/chain-selectors v1.0.30/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= +github.com/smartcontractkit/chain-selectors v1.0.31 h1:oRHyK88KnsCh4OdU2hr0u70pm3KUgyMDyK0v0aOtUk4= +github.com/smartcontractkit/chain-selectors v1.0.31/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec h1:5vS1k8Qn09p8SQ3JzvS8iy4Pve7s3aVq+UPIdl74smY= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec/go.mod h1:4adKaHNaxFsRvV/lYfqtbsWyyvIPUMLR0FdOJN/ljis= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b h1:mm46AlaafEhvGjJvuAb0VoLLM3NKAVnwKZ+iUCNL/sg= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b/go.mod h1:ny87uTW6hLjCTLiBqBRNFEhETSXhHWevYlPclT5lSco= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d h1:0tnjo1gpG16PHAouXamgDAAu6e7PWaM0Ppq6dMWnjx0= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d/go.mod h1:ny87uTW6hLjCTLiBqBRNFEhETSXhHWevYlPclT5lSco= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f h1:BwrIaQIx5Iy6eT+DfLhFfK2XqjxRm74mVdlX8gbu4dw= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f/go.mod h1:wHtwSR3F1CQSJJZDQKuqaqFYnvkT+kMyget7dl8Clvo= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241114154055-8d29ea018b57 h1:1BMTG66HnCIz+KMBWGvyzELNM6VHGwv2WKFhN7H49Sg= diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index cec7e5bb48c..32b64d402b1 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/pelletier/go-toml/v2" + "github.com/prometheus/client_golang/prometheus" "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" @@ -37,6 +38,7 @@ type RelayerFactory struct { logger.Logger *plugins.LoopRegistry loop.GRPCOpts + Registerer prometheus.Registerer MercuryPool wsrpc.Pool CapabilitiesRegistry coretypes.CapabilitiesRegistry HTTPClient *http.Client @@ -81,6 +83,7 @@ func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (m relayerOpts := evmrelay.RelayerOpts{ DS: ccOpts.DS, + Registerer: r.Registerer, CSAETHKeystore: config.CSAETHKeystore, MercuryPool: r.MercuryPool, MercuryConfig: config.MercuryConfig, diff --git a/core/services/job/models.go b/core/services/job/models.go index 423a297c8da..26d563c7ac8 100644 --- a/core/services/job/models.go +++ b/core/services/job/models.go @@ -869,21 +869,30 @@ const ( DefaultSpecType = "" ) +type WorkflowSpecStatus string + +const ( + WorkflowSpecStatusActive WorkflowSpecStatus = "active" + WorkflowSpecStatusPaused WorkflowSpecStatus = "paused" + WorkflowSpecStatusDefault WorkflowSpecStatus = "" +) + type WorkflowSpec struct { ID int32 `toml:"-"` Workflow string `toml:"workflow"` // the raw representation of the workflow Config string `toml:"config" db:"config"` // the raw representation of the config // fields derived from the yaml spec, used for indexing the database // note: i tried to make these private, but translating them to the database seems to require them to be public - WorkflowID string `toml:"-" db:"workflow_id"` // Derived. Do not modify. the CID of the workflow. - WorkflowOwner string `toml:"-" db:"workflow_owner"` // Derived. Do not modify. the owner of the workflow. - WorkflowName string `toml:"-" db:"workflow_name"` // Derived. Do not modify. the name of the workflow. - BinaryURL string `db:"binary_url"` - ConfigURL string `db:"config_url"` - SecretsID sql.NullInt64 `db:"secrets_id"` - CreatedAt time.Time `toml:"-"` - UpdatedAt time.Time `toml:"-"` - SpecType WorkflowSpecType `toml:"spec_type" db:"spec_type"` + WorkflowID string `toml:"-" db:"workflow_id"` // Derived. Do not modify. the CID of the workflow. + WorkflowOwner string `toml:"-" db:"workflow_owner"` // Derived. Do not modify. the owner of the workflow. + WorkflowName string `toml:"-" db:"workflow_name"` // Derived. Do not modify. the name of the workflow. + Status WorkflowSpecStatus `db:"status"` + BinaryURL string `db:"binary_url"` + ConfigURL string `db:"config_url"` + SecretsID sql.NullInt64 `db:"secrets_id"` + CreatedAt time.Time `toml:"-"` + UpdatedAt time.Time `toml:"-"` + SpecType WorkflowSpecType `toml:"spec_type" db:"spec_type"` sdkWorkflow *sdk.WorkflowSpec rawSpec []byte config []byte diff --git a/core/services/job/models_test.go b/core/services/job/models_test.go index 5ef36ea9f48..df52a5cca0c 100644 --- a/core/services/job/models_test.go +++ b/core/services/job/models_test.go @@ -345,8 +345,6 @@ func TestWorkflowSpec_Validate(t *testing.T) { err := w.Validate(testutils.Context(t)) require.NoError(t, err) - assert.Equal(t, "owner", w.WorkflowOwner) - assert.Equal(t, "name", w.WorkflowName) require.NotEmpty(t, w.WorkflowID) }) } diff --git a/core/services/job/testdata/wasm/test_workflow_spec.go b/core/services/job/testdata/wasm/test_workflow_spec.go index 40b9c0bbb67..477ba097ca3 100644 --- a/core/services/job/testdata/wasm/test_workflow_spec.go +++ b/core/services/job/testdata/wasm/test_workflow_spec.go @@ -3,9 +3,6 @@ package main import ( - "encoding/json" - "log" - "github.com/smartcontractkit/chainlink-common/pkg/workflows/wasm" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/cli/cmd/testdata/fixtures/capabilities/basictrigger" @@ -13,12 +10,7 @@ import ( ) func BuildWorkflow(config []byte) *sdk.WorkflowSpecFactory { - params := sdk.NewWorkflowParams{} - if err := json.Unmarshal(config, ¶ms); err != nil { - log.Fatal(err) - } - - workflow := sdk.NewWorkflowSpecFactory(params) + workflow := sdk.NewWorkflowSpecFactory() triggerCfg := basictrigger.TriggerConfig{Name: "trigger", Number: 100} _ = triggerCfg.New(workflow) diff --git a/core/services/llo/bm/dummy_transmitter.go b/core/services/llo/bm/dummy_transmitter.go index b7fa2bd9e15..f62635a7953 100644 --- a/core/services/llo/bm/dummy_transmitter.go +++ b/core/services/llo/bm/dummy_transmitter.go @@ -23,9 +23,11 @@ import ( // A dummy transmitter useful for benchmarking and testing var ( - transmitSuccessCount = promauto.NewCounter(prometheus.CounterOpts{ - Name: "llo_transmit_success_count", - Help: "Running count of successful transmits", + promTransmitSuccessCount = promauto.NewCounter(prometheus.CounterOpts{ + Namespace: "llo", + Subsystem: "dummytransmitter", + Name: "transmit_success_count", + Help: "Running count of successful transmits", }) ) @@ -101,7 +103,7 @@ func (t *transmitter) Transmit( lggr.Debugw(fmt.Sprintf("Failed to decode report with type %s", report.Info.ReportFormat), "err", err) } } - transmitSuccessCount.Inc() + promTransmitSuccessCount.Inc() lggr.Infow("Transmit (dummy)", "digest", digest, "seqNr", seqNr, "report.Report", report.Report, "report.Info", report.Info, "sigs", sigs) return nil } diff --git a/core/services/llo/data_source.go b/core/services/llo/data_source.go index 0585dec49dc..481fd0b790a 100644 --- a/core/services/llo/data_source.go +++ b/core/services/llo/data_source.go @@ -24,14 +24,18 @@ import ( var ( promMissingStreamCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Name: "llo_stream_missing_count", - Help: "Number of times we tried to observe a stream, but it was missing", + Namespace: "llo", + Subsystem: "datasource", + Name: "stream_missing_count", + Help: "Number of times we tried to observe a stream, but it was missing", }, []string{"streamID"}, ) promObservationErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Name: "llo_stream_observation_error_count", - Help: "Number of times we tried to observe a stream, but it failed with an error", + Namespace: "llo", + Subsystem: "datasource", + Name: "stream_observation_error_count", + Help: "Number of times we tried to observe a stream, but it failed with an error", }, []string{"streamID"}, ) diff --git a/core/services/llo/mercurytransmitter/queue.go b/core/services/llo/mercurytransmitter/queue.go index eae9a0b9d0c..6610010a469 100644 --- a/core/services/llo/mercurytransmitter/queue.go +++ b/core/services/llo/mercurytransmitter/queue.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "strconv" "sync" "time" @@ -22,9 +23,11 @@ type asyncDeleter interface { var _ services.Service = (*transmitQueue)(nil) -var transmitQueueLoad = promauto.NewGaugeVec(prometheus.GaugeOpts{ - Name: "llo_transmit_queue_load", - Help: "Current count of items in the transmit queue", +var promTransmitQueueLoad = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: "llo", + Subsystem: "mercurytransmitter", + Name: "transmit_queue_load", + Help: "Current count of items in the transmit queue", }, []string{"donID", "serverURL", "capacity"}, ) @@ -75,7 +78,7 @@ func NewTransmitQueue(lggr logger.Logger, serverURL string, maxlen int, asyncDel maxlen, false, nil, - transmitQueueLoad.WithLabelValues(fmt.Sprintf("%d", asyncDeleter.DonID()), serverURL, fmt.Sprintf("%d", maxlen)), + promTransmitQueueLoad.WithLabelValues(strconv.FormatUint(uint64(asyncDeleter.DonID()), 10), serverURL, strconv.FormatInt(int64(maxlen), 10)), } } diff --git a/core/services/llo/mercurytransmitter/server.go b/core/services/llo/mercurytransmitter/server.go index 22472349c25..308ff6a73a4 100644 --- a/core/services/llo/mercurytransmitter/server.go +++ b/core/services/llo/mercurytransmitter/server.go @@ -3,7 +3,9 @@ package mercurytransmitter import ( "context" "fmt" + "strconv" "sync" + "sync/atomic" "time" "github.com/jpillora/backoff" @@ -28,27 +30,35 @@ import ( ) var ( - transmitQueueDeleteErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Name: "llo_mercury_transmit_queue_delete_error_count", - Help: "Running count of DB errors when trying to delete an item from the queue DB", + promTransmitQueueDeleteErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: "llo", + Subsystem: "mercurytransmitter", + Name: "transmit_queue_delete_error_count", + Help: "Running count of DB errors when trying to delete an item from the queue DB", }, []string{"donID", "serverURL"}, ) - transmitQueueInsertErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Name: "llo_mercury_transmit_queue_insert_error_count", - Help: "Running count of DB errors when trying to insert an item into the queue DB", + promTransmitQueueInsertErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: "llo", + Subsystem: "mercurytransmitter", + Name: "transmit_queue_insert_error_count", + Help: "Running count of DB errors when trying to insert an item into the queue DB", }, []string{"donID", "serverURL"}, ) - transmitQueuePushErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Name: "llo_mercury_transmit_queue_push_error_count", - Help: "Running count of DB errors when trying to push an item onto the queue", + promTransmitQueuePushErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: "llo", + Subsystem: "mercurytransmitter", + Name: "transmit_queue_push_error_count", + Help: "Running count of DB errors when trying to push an item onto the queue", }, []string{"donID", "serverURL"}, ) - transmitServerErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Name: "llo_mercury_transmit_server_error_count", - Help: "Number of errored transmissions that failed due to an error returned by the mercury server", + promTransmitServerErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: "llo", + Subsystem: "mercurytransmitter", + Name: "transmit_server_error_count", + Help: "Number of errored transmissions that failed due to an error returned by the mercury server", }, []string{"donID", "serverURL", "code"}, ) @@ -83,6 +93,9 @@ type server struct { transmitQueueDeleteErrorCount prometheus.Counter transmitQueueInsertErrorCount prometheus.Counter transmitQueuePushErrorCount prometheus.Counter + + transmitThreadBusyCount atomic.Int32 + deleteThreadBusyCount atomic.Int32 } type QueueConfig interface { @@ -100,7 +113,7 @@ func newServer(lggr logger.Logger, verboseLogging bool, cfg QueueConfig, client codecLggr = corelogger.NullLogger } - return &server{ + s := &server{ logger.Sugared(lggr), verboseLogging, cfg.TransmitTimeout().Duration(), @@ -111,13 +124,17 @@ func newServer(lggr logger.Logger, verboseLogging bool, cfg QueueConfig, client serverURL, evm.NewReportCodecPremiumLegacy(codecLggr), llo.JSONReportCodec{}, - transmitSuccessCount.WithLabelValues(donIDStr, serverURL), - transmitDuplicateCount.WithLabelValues(donIDStr, serverURL), - transmitConnectionErrorCount.WithLabelValues(donIDStr, serverURL), - transmitQueueDeleteErrorCount.WithLabelValues(donIDStr, serverURL), - transmitQueueInsertErrorCount.WithLabelValues(donIDStr, serverURL), - transmitQueuePushErrorCount.WithLabelValues(donIDStr, serverURL), + promTransmitSuccessCount.WithLabelValues(donIDStr, serverURL), + promTransmitDuplicateCount.WithLabelValues(donIDStr, serverURL), + promTransmitConnectionErrorCount.WithLabelValues(donIDStr, serverURL), + promTransmitQueueDeleteErrorCount.WithLabelValues(donIDStr, serverURL), + promTransmitQueueInsertErrorCount.WithLabelValues(donIDStr, serverURL), + promTransmitQueuePushErrorCount.WithLabelValues(donIDStr, serverURL), + atomic.Int32{}, + atomic.Int32{}, } + + return s } func (s *server) HealthReport() map[string]error { @@ -144,6 +161,7 @@ func (s *server) runDeleteQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup select { case hash := <-s.deleteQueue: for { + s.deleteThreadBusyCount.Add(1) if err := s.pm.orm.Delete(ctx, [][32]byte{hash}); err != nil { s.lggr.Errorw("Failed to delete transmission record", "err", err, "transmissionHash", hash) s.transmitQueueDeleteErrorCount.Inc() @@ -152,6 +170,7 @@ func (s *server) runDeleteQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup // Wait a backoff duration before trying to delete again continue case <-stopCh: + s.deleteThreadBusyCount.Add(-1) // abort and return immediately on stop even if items remain in queue return } @@ -160,6 +179,7 @@ func (s *server) runDeleteQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup } // success b.Reset() + s.deleteThreadBusyCount.Add(-1) case <-stopCh: // abort and return immediately on stop even if items remain in queue return @@ -179,61 +199,69 @@ func (s *server) runQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup, donI } ctx, cancel := stopCh.NewCtx() defer cancel() - for { - t := s.q.BlockingPop() - if t == nil { - // queue was closed - return - } - req, res, err := func(ctx context.Context) (*pb.TransmitRequest, *pb.TransmitResponse, error) { - ctx, cancelFn := context.WithTimeout(ctx, utils.WithJitter(s.transmitTimeout)) - defer cancelFn() - return s.transmit(ctx, t) - }(ctx) - if ctx.Err() != nil { - // only canceled on transmitter close so we can exit - return - } else if err != nil { - s.transmitConnectionErrorCount.Inc() - s.lggr.Errorw("Transmit report failed", "err", err, "req.Payload", req.Payload, "req.ReportFormat", req.ReportFormat, "transmission", t) - if ok := s.q.Push(t); !ok { - s.lggr.Error("Failed to push report to transmit queue; queue is closed") - return + cont := true + for cont { + cont = func() bool { + t := s.q.BlockingPop() + if t == nil { + // queue was closed + return false } - // Wait a backoff duration before pulling the most recent transmission - // the heap - select { - case <-time.After(b.Duration()): - continue - case <-stopCh: - return + + s.transmitThreadBusyCount.Add(1) + defer s.transmitThreadBusyCount.Add(-1) + + req, res, err := func(ctx context.Context) (*pb.TransmitRequest, *pb.TransmitResponse, error) { + ctx, cancelFn := context.WithTimeout(ctx, utils.WithJitter(s.transmitTimeout)) + defer cancelFn() + return s.transmit(ctx, t) + }(ctx) + if ctx.Err() != nil { + // only canceled on transmitter close so we can exit + return false + } else if err != nil { + s.transmitConnectionErrorCount.Inc() + s.lggr.Errorw("Transmit report failed", "err", err, "req.Payload", req.Payload, "req.ReportFormat", req.ReportFormat, "transmission", t) + if ok := s.q.Push(t); !ok { + s.lggr.Error("Failed to push report to transmit queue; queue is closed") + return false + } + // Wait a backoff duration before pulling the most recent transmission + // the heap + select { + case <-time.After(b.Duration()): + return true + case <-stopCh: + return false + } } - } - b.Reset() - if res.Error == "" { - s.transmitSuccessCount.Inc() - s.lggr.Debugw("Transmit report success", "req.ReportFormat", req.ReportFormat, "req.Payload", req.Payload, "transmission", t, "response", res) - } else { - // We don't need to retry here because the mercury server - // has confirmed it received the report. We only need to retry - // on networking/unknown errors - switch res.Code { - case DuplicateReport: + b.Reset() + if res.Error == "" { s.transmitSuccessCount.Inc() - s.transmitDuplicateCount.Inc() - s.lggr.Debugw("Transmit report success; duplicate report", "req.ReportFormat", req.ReportFormat, "req.Payload", req.Payload, "transmission", t, "response", res) - default: - transmitServerErrorCount.WithLabelValues(donIDStr, s.url, fmt.Sprintf("%d", res.Code)).Inc() - s.lggr.Errorw("Transmit report failed; mercury server returned error", "req.ReportFormat", req.ReportFormat, "req.Payload", req.Payload, "response", res, "transmission", t, "err", res.Error, "code", res.Code) + s.lggr.Debugw("Transmit report success", "req.ReportFormat", req.ReportFormat, "req.Payload", req.Payload, "transmission", t, "response", res) + } else { + // We don't need to retry here because the mercury server + // has confirmed it received the report. We only need to retry + // on networking/unknown errors + switch res.Code { + case DuplicateReport: + s.transmitSuccessCount.Inc() + s.transmitDuplicateCount.Inc() + s.lggr.Debugw("Transmit report success; duplicate report", "req.ReportFormat", req.ReportFormat, "req.Payload", req.Payload, "transmission", t, "response", res) + default: + promTransmitServerErrorCount.WithLabelValues(donIDStr, s.url, strconv.FormatInt(int64(res.Code), 10)).Inc() + s.lggr.Errorw("Transmit report failed; mercury server returned error", "req.ReportFormat", req.ReportFormat, "req.Payload", req.Payload, "response", res, "transmission", t, "err", res.Error, "code", res.Code) + } } - } - select { - case s.deleteQueue <- t.Hash(): - default: - s.lggr.Criticalw("Delete queue is full", "transmission", t, "transmissionHash", fmt.Sprintf("%x", t.Hash())) - } + select { + case s.deleteQueue <- t.Hash(): + default: + s.lggr.Criticalw("Delete queue is full", "transmission", t, "transmissionHash", fmt.Sprintf("%x", t.Hash())) + } + return true + }() } } diff --git a/core/services/llo/mercurytransmitter/transmitter.go b/core/services/llo/mercurytransmitter/transmitter.go index 024a98174c6..8e60bf938a5 100644 --- a/core/services/llo/mercurytransmitter/transmitter.go +++ b/core/services/llo/mercurytransmitter/transmitter.go @@ -33,21 +33,27 @@ const ( ) var ( - transmitSuccessCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Name: "llo_mercury_transmit_success_count", - Help: "Number of successful transmissions (duplicates are counted as success)", + promTransmitSuccessCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: "llo", + Subsystem: "mercurytransmitter", + Name: "transmit_success_count", + Help: "Number of successful transmissions (duplicates are counted as success)", }, []string{"donID", "serverURL"}, ) - transmitDuplicateCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Name: "llo_mercury_transmit_duplicate_count", - Help: "Number of transmissions where the server told us it was a duplicate", + promTransmitDuplicateCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: "llo", + Subsystem: "mercurytransmitter", + Name: "transmit_duplicate_count", + Help: "Number of transmissions where the server told us it was a duplicate", }, []string{"donID", "serverURL"}, ) - transmitConnectionErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Name: "llo_mercury_transmit_connection_error_count", - Help: "Number of errored transmissions that failed due to problem with the connection", + promTransmitConnectionErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: "llo", + Subsystem: "mercurytransmitter", + Name: "transmit_connection_error_count", + Help: "Number of errored transmissions that failed due to problem with the connection", }, []string{"donID", "serverURL"}, ) @@ -107,8 +113,10 @@ type transmitter struct { verboseLogging bool cfg Config - orm ORM - servers map[string]*server + orm ORM + servers map[string]*server + registerer prometheus.Registerer + collectors []prometheus.Collector donID uint32 fromAccount string @@ -119,6 +127,7 @@ type transmitter struct { type Opts struct { Lggr logger.Logger + Registerer prometheus.Registerer VerboseLogging bool Cfg Config Clients map[string]wsrpc.Client @@ -145,6 +154,8 @@ func newTransmitter(opts Opts) *transmitter { opts.Cfg, opts.ORM, servers, + opts.Registerer, + nil, opts.DonID, fmt.Sprintf("%x", opts.FromAccount), make(services.StopChan), @@ -183,6 +194,31 @@ func (mt *transmitter) Start(ctx context.Context) (err error) { go s.runDeleteQueueLoop(mt.stopCh, mt.wg) go s.runQueueLoop(mt.stopCh, mt.wg, donIDStr) } + mt.collectors = append(mt.collectors, prometheus.NewGaugeFunc( + prometheus.GaugeOpts{ + Namespace: "llo", + Subsystem: "mercurytransmitter", + Name: "concurrent_transmit_gauge", + Help: "Gauge that measures the number of transmit threads currently waiting on a remote transmit call. You may wish to alert if this exceeds some number for a given period of time, or if it ever reaches its max.", + ConstLabels: prometheus.Labels{"donID": donIDStr, "serverURL": s.url, "maxConcurrentTransmits": strconv.FormatInt(int64(nThreads), 10)}, + }, func() float64 { + return float64(s.transmitThreadBusyCount.Load()) + })) + mt.collectors = append(mt.collectors, prometheus.NewGaugeFunc( + prometheus.GaugeOpts{ + Namespace: "llo", + Subsystem: "mercurytransmitter", + Name: "concurrent_delete_gauge", + Help: "Gauge that measures the number of delete threads currently waiting on a delete call to the DB. You may wish to alert if this exceeds some number for a given period of time, or if it ever reaches its max.", + ConstLabels: prometheus.Labels{"donID": donIDStr, "serverURL": s.url, "maxConcurrentDeletes": strconv.FormatInt(int64(nThreads), 10)}, + }, func() float64 { + return float64(s.deleteThreadBusyCount.Load()) + })) + for _, c := range mt.collectors { + if err := mt.registerer.Register(c); err != nil { + return err + } + } } if err := (&services.MultiStart{}).Start(ctx, startClosers...); err != nil { return err @@ -214,7 +250,12 @@ func (mt *transmitter) Close() error { closers = append(closers, s.pm) closers = append(closers, s.c) } - return services.CloseAll(closers...) + err := services.CloseAll(closers...) + // Unregister all the gauge funcs + for _, c := range mt.collectors { + mt.registerer.Unregister(c) + } + return err }) } diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go index eaa7b10b0df..6a220ececf7 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -789,10 +789,14 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh // │ Deploy Pools │ // ================================================================ + // All the tokens deployed above have 18 decimals + tokenDecimals := uint8(18) + sourcePoolLinkAddress, _, _, err := lock_release_token_pool.DeployLockReleaseTokenPool( sourceUser, sourceChain.Client(), sourceLinkTokenAddress, + tokenDecimals, []common.Address{}, armProxySourceAddress, true, @@ -809,6 +813,7 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh sourceUser, sourceChain.Client(), sourceWeth9addr, + tokenDecimals, []common.Address{}, armProxySourceAddress, true, @@ -827,6 +832,7 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh destUser, destChain.Client(), destLinkTokenAddress, + tokenDecimals, []common.Address{}, armProxyDestAddress, true, @@ -858,6 +864,7 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh destUser, destChain.Client(), destWeth9addr, + tokenDecimals, []common.Address{}, armProxyDestAddress, true, @@ -892,11 +899,11 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh require.NoError(t, err) _, err = sourceLinkPool.ApplyChainUpdates( sourceUser, + []uint64{}, []lock_release_token_pool.TokenPoolChainUpdate{{ RemoteChainSelector: DestChainSelector, - RemotePoolAddress: abiEncodedDestLinkPool, + RemotePoolAddresses: [][]byte{abiEncodedDestLinkPool}, RemoteTokenAddress: abiEncodedDestLinkTokenAddress, - Allowed: true, OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ IsEnabled: true, Capacity: HundredLink, @@ -917,11 +924,11 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh require.NoError(t, err) _, err = sourceWeth9Pool.ApplyChainUpdates( sourceUser, + []uint64{}, []lock_release_token_pool.TokenPoolChainUpdate{{ RemoteChainSelector: DestChainSelector, - RemotePoolAddress: abiEncodedDestWrappedPool, + RemotePoolAddresses: [][]byte{abiEncodedDestWrappedPool}, RemoteTokenAddress: abiEncodedDestWrappedTokenAddr, - Allowed: true, OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ IsEnabled: true, Capacity: HundredLink, @@ -943,11 +950,11 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh require.NoError(t, err) _, err = destLinkPool.ApplyChainUpdates( destUser, + []uint64{}, []lock_release_token_pool.TokenPoolChainUpdate{{ RemoteChainSelector: SourceChainSelector, - RemotePoolAddress: abiEncodedSourceLinkPool, + RemotePoolAddresses: [][]byte{abiEncodedSourceLinkPool}, RemoteTokenAddress: abiEncodedSourceLinkTokenAddr, - Allowed: true, OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ IsEnabled: true, Capacity: HundredLink, @@ -968,11 +975,11 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh require.NoError(t, err) _, err = destWrappedPool.ApplyChainUpdates( destUser, + []uint64{}, []lock_release_token_pool.TokenPoolChainUpdate{{ RemoteChainSelector: SourceChainSelector, - RemotePoolAddress: abiEncodedSourceWrappedPool, + RemotePoolAddresses: [][]byte{abiEncodedSourceWrappedPool}, RemoteTokenAddress: abiEncodedSourceWrappedTokenAddr, - Allowed: true, OutboundRateLimiterConfig: lock_release_token_pool.RateLimiterConfig{ IsEnabled: true, Capacity: HundredLink, diff --git a/core/services/relay/evm/capabilities/workflows/syncer/workflow_syncer_test.go b/core/services/relay/evm/capabilities/workflows/syncer/workflow_syncer_test.go index d6f507eac20..ba29e98526e 100644 --- a/core/services/relay/evm/capabilities/workflows/syncer/workflow_syncer_test.go +++ b/core/services/relay/evm/capabilities/workflows/syncer/workflow_syncer_test.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/chainlink-common/pkg/custmsg" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/workflow/generated/workflow_registry_wrapper" @@ -29,6 +30,7 @@ func Test_SecretsWorker(t *testing.T) { var ( ctx = coretestutils.Context(t) lggr = logger.TestLogger(t) + emitter = custmsg.NewLabeler() backendTH = testutils.NewEVMBackendTH(t) db = pgtest.NewSqlxDB(t) orm = syncer.NewWorkflowRegistryDS(db, lggr) @@ -119,6 +121,7 @@ func Test_SecretsWorker(t *testing.T) { wfRegistryAddr.Hex(), nil, nil, + emitter, syncer.WithTicker(giveTicker.C), ) diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 8008fc4fd9e..0be78caf249 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -17,6 +17,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" pkgerrors "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" "golang.org/x/exp/maps" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" @@ -143,6 +144,7 @@ type Relayer struct { ds sqlutil.DataSource chain legacyevm.Chain lggr logger.SugaredLogger + registerer prometheus.Registerer ks CSAETHKeystore mercuryPool wsrpc.Pool codec commontypes.Codec @@ -169,7 +171,8 @@ type MercuryConfig interface { } type RelayerOpts struct { - DS sqlutil.DataSource + DS sqlutil.DataSource + Registerer prometheus.Registerer CSAETHKeystore MercuryPool wsrpc.Pool RetirementReportCache llo.RetirementReportCache @@ -214,6 +217,7 @@ func NewRelayer(ctx context.Context, lggr logger.Logger, chain legacyevm.Chain, ds: opts.DS, chain: chain, lggr: sugared, + registerer: opts.Registerer, ks: opts.CSAETHKeystore, mercuryPool: opts.MercuryPool, cdcFactory: cdcFactory, @@ -563,6 +567,7 @@ func (r *Relayer) NewLLOProvider(ctx context.Context, rargs commontypes.RelayArg VerboseLogging: r.mercuryCfg.VerboseLogging(), MercuryTransmitterOpts: mercurytransmitter.Opts{ Lggr: r.lggr, + Registerer: r.registerer, VerboseLogging: r.mercuryCfg.VerboseLogging(), Cfg: r.mercuryCfg.Transmitter(), Clients: clients, diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index e264ee138a1..69655b5b39c 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -1263,7 +1263,7 @@ func NewEngine(ctx context.Context, cfg Config) (engine *Engine, err error) { engine = &Engine{ cma: cma, logger: cfg.Lggr.Named("WorkflowEngine").With("workflowID", cfg.WorkflowID), - metrics: workflowsMetricLabeler{metrics.NewLabeler().With(platform.KeyWorkflowID, cfg.WorkflowID, platform.KeyWorkflowOwner, cfg.WorkflowOwner, platform.KeyWorkflowName, workflow.name)}, + metrics: workflowsMetricLabeler{metrics.NewLabeler().With(platform.KeyWorkflowID, cfg.WorkflowID, platform.KeyWorkflowOwner, cfg.WorkflowOwner, platform.KeyWorkflowName, cfg.WorkflowName)}, registry: cfg.Registry, workflow: workflow, secretsFetcher: cfg.SecretsFetcher, diff --git a/core/services/workflows/syncer/handler.go b/core/services/workflows/syncer/handler.go index 01e13d106f9..5ccb3f5e180 100644 --- a/core/services/workflows/syncer/handler.go +++ b/core/services/workflows/syncer/handler.go @@ -2,12 +2,18 @@ package syncer import ( "context" + "crypto/sha256" "encoding/hex" "errors" "fmt" + "github.com/smartcontractkit/chainlink-common/pkg/custmsg" "github.com/smartcontractkit/chainlink-common/pkg/types/core" + "github.com/smartcontractkit/chainlink-common/pkg/workflows/wasm/host" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/platform" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + "github.com/smartcontractkit/chainlink/v2/core/services/workflows" "github.com/smartcontractkit/chainlink/v2/core/services/workflows/store" ) @@ -87,15 +93,28 @@ type WorkflowRegistryWorkflowDeletedV1 struct { WorkflowName string } +type secretsFetcher interface { + SecretsFor(ctx context.Context, workflowOwner, workflowName string) (map[string]string, error) +} + +// secretsFetcherFunc implements the secretsFetcher interface for a function. +type secretsFetcherFunc func(ctx context.Context, workflowOwner, workflowName string) (map[string]string, error) + +func (f secretsFetcherFunc) SecretsFor(ctx context.Context, workflowOwner, workflowName string) (map[string]string, error) { + return f(ctx, workflowOwner, workflowName) +} + // eventHandler is a handler for WorkflowRegistryEvent events. Each event type has a corresponding // method that handles the event. type eventHandler struct { lggr logger.Logger - orm WorkflowSecretsDS + orm WorkflowRegistryDS fetcher FetcherFunc workflowStore store.Store capRegistry core.CapabilitiesRegistry engineRegistry *engineRegistry + emitter custmsg.MessageEmitter + secretsFetcher secretsFetcher } // newEventHandler returns a new eventHandler instance. @@ -106,6 +125,8 @@ func newEventHandler( workflowStore store.Store, capRegistry core.CapabilitiesRegistry, engineRegistry *engineRegistry, + emitter custmsg.MessageEmitter, + secretsFetcher secretsFetcher, ) *eventHandler { return &eventHandler{ lggr: lggr, @@ -114,15 +135,50 @@ func newEventHandler( workflowStore: workflowStore, capRegistry: capRegistry, engineRegistry: engineRegistry, + emitter: emitter, + secretsFetcher: secretsFetcher, } } func (h *eventHandler) Handle(ctx context.Context, event WorkflowRegistryEvent) error { switch event.EventType { case ForceUpdateSecretsEvent: - return h.forceUpdateSecretsEvent(ctx, event) + payload, ok := event.Data.(WorkflowRegistryForceUpdateSecretsRequestedV1) + if !ok { + return newHandlerTypeError(event.Data) + } + + cma := h.emitter.With( + platform.KeyWorkflowName, payload.WorkflowName, + platform.KeyWorkflowOwner, hex.EncodeToString(payload.Owner), + ) + + if err := h.forceUpdateSecretsEvent(ctx, payload); err != nil { + logCustMsg(ctx, cma, fmt.Sprintf("failed to handle force update secrets event: %v", err), h.lggr) + return err + } + + return nil case WorkflowRegisteredEvent: - return h.workflowRegisteredEvent(ctx, event) + payload, ok := event.Data.(WorkflowRegistryWorkflowRegisteredV1) + if !ok { + return newHandlerTypeError(event.Data) + } + wfID := hex.EncodeToString(payload.WorkflowID[:]) + + cma := h.emitter.With( + platform.KeyWorkflowID, wfID, + platform.KeyWorkflowName, payload.WorkflowName, + platform.KeyWorkflowOwner, hex.EncodeToString(payload.WorkflowOwner), + ) + + if err := h.workflowRegisteredEvent(ctx, payload); err != nil { + logCustMsg(ctx, cma, fmt.Sprintf("failed to handle workflow registered event: %v", err), h.lggr) + return err + } + + h.lggr.Debugf("workflow 0x%x registered and started", wfID) + return nil case WorkflowUpdatedEvent: return h.workflowUpdatedEvent(ctx, event) case WorkflowPausedEvent: @@ -135,12 +191,97 @@ func (h *eventHandler) Handle(ctx context.Context, event WorkflowRegistryEvent) } // workflowRegisteredEvent handles the WorkflowRegisteredEvent event type. -// TODO: Implement this method func (h *eventHandler) workflowRegisteredEvent( - _ context.Context, - _ WorkflowRegistryEvent, + ctx context.Context, + payload WorkflowRegistryWorkflowRegisteredV1, ) error { - return ErrNotImplemented + wfID := hex.EncodeToString(payload.WorkflowID[:]) + + // Download the contents of binaryURL, configURL and secretsURL and cache them locally. + binary, err := h.fetcher(ctx, payload.BinaryURL) + if err != nil { + return fmt.Errorf("failed to fetch binary from %s : %w", payload.BinaryURL, err) + } + + config, err := h.fetcher(ctx, payload.ConfigURL) + if err != nil { + return fmt.Errorf("failed to fetch config from %s : %w", payload.ConfigURL, err) + } + + secrets, err := h.fetcher(ctx, payload.SecretsURL) + if err != nil { + return fmt.Errorf("failed to fetch secrets from %s : %w", payload.SecretsURL, err) + } + + // Calculate the hash of the binary and config files + hash := workflowID(binary, config, []byte(payload.SecretsURL)) + + // Pre-check: verify that the workflowID matches; if it doesn’t abort and log an error via Beholder. + if hash != wfID { + return fmt.Errorf("workflowID mismatch: %s != %s", hash, wfID) + } + + // Save the workflow secrets + urlHash, err := h.orm.GetSecretsURLHash(payload.WorkflowOwner, []byte(payload.SecretsURL)) + if err != nil { + return fmt.Errorf("failed to get secrets URL hash: %w", err) + } + + // Create a new entry in the workflow_spec table corresponding for the new workflow, with the contents of the binaryURL + configURL in the table + status := job.WorkflowSpecStatusActive + if payload.Status == 1 { + status = job.WorkflowSpecStatusPaused + } + + entry := &job.WorkflowSpec{ + Workflow: hex.EncodeToString(binary), + Config: string(config), + WorkflowID: wfID, + Status: status, + WorkflowOwner: hex.EncodeToString(payload.WorkflowOwner), + WorkflowName: payload.WorkflowName, + SpecType: job.WASMFile, + BinaryURL: payload.BinaryURL, + ConfigURL: payload.ConfigURL, + } + if _, err = h.orm.UpsertWorkflowSpecWithSecrets(ctx, entry, payload.SecretsURL, hex.EncodeToString(urlHash), string(secrets)); err != nil { + return fmt.Errorf("failed to upsert workflow spec with secrets: %w", err) + } + + if status != job.WorkflowSpecStatusActive { + return nil + } + + // If status == active, start a new WorkflowEngine instance, and add it to local engine registry + moduleConfig := &host.ModuleConfig{Logger: h.lggr, Labeler: h.emitter} + sdkSpec, err := host.GetWorkflowSpec(ctx, moduleConfig, binary, config) + if err != nil { + return fmt.Errorf("failed to get workflow sdk spec: %w", err) + } + + cfg := workflows.Config{ + Lggr: h.lggr, + Workflow: *sdkSpec, + WorkflowID: wfID, + WorkflowOwner: hex.EncodeToString(payload.WorkflowOwner), + WorkflowName: payload.WorkflowName, + Registry: h.capRegistry, + Store: h.workflowStore, + Config: config, + Binary: binary, + SecretsFetcher: h.secretsFetcher, + } + e, err := workflows.NewEngine(ctx, cfg) + if err != nil { + return fmt.Errorf("failed to create workflow engine: %w", err) + } + + if err := e.Start(ctx); err != nil { + return fmt.Errorf("failed to start workflow engine: %w", err) + } + + h.engineRegistry.Add(wfID, e) + return nil } // workflowUpdatedEvent handles the WorkflowUpdatedEvent event type. @@ -170,32 +311,47 @@ func (h *eventHandler) workflowActivatedEvent( // forceUpdateSecretsEvent handles the ForceUpdateSecretsEvent event type. func (h *eventHandler) forceUpdateSecretsEvent( ctx context.Context, - event WorkflowRegistryEvent, + payload WorkflowRegistryForceUpdateSecretsRequestedV1, ) error { // Get the URL of the secrets file from the event data - data, ok := event.Data.(WorkflowRegistryForceUpdateSecretsRequestedV1) - if !ok { - return fmt.Errorf("invalid data type %T for event", event.Data) - } - - hash := hex.EncodeToString(data.SecretsURLHash) + hash := hex.EncodeToString(payload.SecretsURLHash) url, err := h.orm.GetSecretsURLByHash(ctx, hash) if err != nil { - h.lggr.Errorf("failed to get URL by hash %s : %s", hash, err) - return err + return fmt.Errorf("failed to get URL by hash %s : %w", hash, err) } // Fetch the contents of the secrets file from the url via the fetcher secrets, err := h.fetcher(ctx, url) if err != nil { - return err + return fmt.Errorf("failed to fetch secrets from url %s : %w", url, err) } // Update the secrets in the ORM if _, err := h.orm.Update(ctx, hash, string(secrets)); err != nil { - return err + return fmt.Errorf("failed to update secrets: %w", err) } return nil } + +// workflowID returns a hex encoded sha256 hash of the wasm, config and secretsURL. +func workflowID(wasm, config, secretsURL []byte) string { + sum := sha256.New() + sum.Write(wasm) + sum.Write(config) + sum.Write(secretsURL) + return hex.EncodeToString(sum.Sum(nil)) +} + +// logCustMsg emits a custom message to the external sink and logs an error if that fails. +func logCustMsg(ctx context.Context, cma custmsg.MessageEmitter, msg string, log logger.Logger) { + err := cma.Emit(ctx, msg) + if err != nil { + log.Helper(1).Errorf("failed to send custom message with msg: %s, err: %v", msg, err) + } +} + +func newHandlerTypeError(data any) error { + return fmt.Errorf("invalid data type %T for event", data) +} diff --git a/core/services/workflows/syncer/handler_test.go b/core/services/workflows/syncer/handler_test.go index 17c980e4f56..42da3e8de9d 100644 --- a/core/services/workflows/syncer/handler_test.go +++ b/core/services/workflows/syncer/handler_test.go @@ -5,18 +5,43 @@ import ( "encoding/hex" "testing" + "github.com/smartcontractkit/chainlink-common/pkg/custmsg" + "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/wasmtest" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" + wfstore "github.com/smartcontractkit/chainlink/v2/core/services/workflows/store" "github.com/smartcontractkit/chainlink/v2/core/services/workflows/syncer/mocks" "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" "github.com/smartcontractkit/chainlink/v2/core/utils/matches" + "github.com/jonboulle/clockwork" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +type mockFetchResp struct { + Body []byte + Err error +} + +type mockFetcher struct { + responseMap map[string]mockFetchResp +} + +func (m *mockFetcher) Fetch(_ context.Context, url string) ([]byte, error) { + return m.responseMap[url].Body, m.responseMap[url].Err +} + +func newMockFetcher(m map[string]mockFetchResp) FetcherFunc { + return (&mockFetcher{responseMap: m}).Fetch +} + func Test_Handler(t *testing.T) { lggr := logger.TestLogger(t) + emitter := custmsg.NewLabeler() t.Run("success", func(t *testing.T) { mockORM := mocks.NewORM(t) ctx := testutils.Context(t) @@ -38,7 +63,7 @@ func Test_Handler(t *testing.T) { } mockORM.EXPECT().GetSecretsURLByHash(matches.AnyContext, giveHash).Return(giveURL, nil) mockORM.EXPECT().Update(matches.AnyContext, giveHash, "contents").Return(int64(1), nil) - h := newEventHandler(lggr, mockORM, fetcher, nil, nil, nil) + h := newEventHandler(lggr, mockORM, fetcher, nil, nil, nil, emitter, nil) err = h.Handle(ctx, giveEvent) require.NoError(t, err) }) @@ -52,7 +77,7 @@ func Test_Handler(t *testing.T) { return []byte("contents"), nil } - h := newEventHandler(lggr, mockORM, fetcher, nil, nil, nil) + h := newEventHandler(lggr, mockORM, fetcher, nil, nil, nil, emitter, nil) err := h.Handle(ctx, giveEvent) require.Error(t, err) require.Contains(t, err.Error(), "event type unsupported") @@ -61,7 +86,7 @@ func Test_Handler(t *testing.T) { t.Run("fails to get secrets url", func(t *testing.T) { mockORM := mocks.NewORM(t) ctx := testutils.Context(t) - h := newEventHandler(lggr, mockORM, nil, nil, nil, nil) + h := newEventHandler(lggr, mockORM, nil, nil, nil, nil, emitter, nil) giveURL := "https://original-url.com" giveBytes, err := crypto.Keccak256([]byte(giveURL)) require.NoError(t, err) @@ -101,7 +126,7 @@ func Test_Handler(t *testing.T) { return nil, assert.AnError } mockORM.EXPECT().GetSecretsURLByHash(matches.AnyContext, giveHash).Return(giveURL, nil) - h := newEventHandler(lggr, mockORM, fetcher, nil, nil, nil) + h := newEventHandler(lggr, mockORM, fetcher, nil, nil, nil, emitter, nil) err = h.Handle(ctx, giveEvent) require.Error(t, err) require.ErrorIs(t, err, assert.AnError) @@ -128,9 +153,140 @@ func Test_Handler(t *testing.T) { } mockORM.EXPECT().GetSecretsURLByHash(matches.AnyContext, giveHash).Return(giveURL, nil) mockORM.EXPECT().Update(matches.AnyContext, giveHash, "contents").Return(0, assert.AnError) - h := newEventHandler(lggr, mockORM, fetcher, nil, nil, nil) + h := newEventHandler(lggr, mockORM, fetcher, nil, nil, nil, emitter, nil) err = h.Handle(ctx, giveEvent) require.Error(t, err) require.ErrorIs(t, err, assert.AnError) }) } + +const ( + binaryLocation = "test/simple/cmd/testmodule.wasm" + binaryCmd = "core/capabilities/compute/test/simple/cmd" +) + +func Test_workflowRegisteredHandler(t *testing.T) { + t.Run("success with paused workflow registered", func(t *testing.T) { + var ( + ctx = testutils.Context(t) + lggr = logger.TestLogger(t) + db = pgtest.NewSqlxDB(t) + orm = NewWorkflowRegistryDS(db, lggr) + emitter = custmsg.NewLabeler() + + binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) + config = []byte("") + secretsURL = "http://example.com" + binaryURL = "http://example.com/binary" + configURL = "http://example.com/config" + wfOwner = []byte("0xOwner") + + fetcher = newMockFetcher(map[string]mockFetchResp{ + binaryURL: {Body: binary, Err: nil}, + configURL: {Body: config, Err: nil}, + secretsURL: {Body: []byte("secrets"), Err: nil}, + }) + ) + + giveWFID := workflowID(binary, config, []byte(secretsURL)) + + b, err := hex.DecodeString(giveWFID) + require.NoError(t, err) + wfID := make([]byte, 32) + copy(wfID, b) + + paused := WorkflowRegistryWorkflowRegisteredV1{ + Status: uint8(1), + WorkflowID: [32]byte(wfID), + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, + } + + h := &eventHandler{ + lggr: lggr, + orm: orm, + fetcher: fetcher, + emitter: emitter, + } + err = h.workflowRegisteredEvent(ctx, paused) + require.NoError(t, err) + + // Verify the record is updated in the database + dbSpec, err := orm.GetWorkflowSpec(ctx, hex.EncodeToString(wfOwner), "workflow-name") + require.NoError(t, err) + require.Equal(t, hex.EncodeToString(wfOwner), dbSpec.WorkflowOwner) + require.Equal(t, "workflow-name", dbSpec.WorkflowName) + require.Equal(t, job.WorkflowSpecStatusPaused, dbSpec.Status) + }) + + t.Run("success with active workflow registered", func(t *testing.T) { + var ( + ctx = testutils.Context(t) + lggr = logger.TestLogger(t) + db = pgtest.NewSqlxDB(t) + orm = NewWorkflowRegistryDS(db, lggr) + emitter = custmsg.NewLabeler() + + binary = wasmtest.CreateTestBinary(binaryCmd, binaryLocation, true, t) + config = []byte("") + secretsURL = "http://example.com" + binaryURL = "http://example.com/binary" + configURL = "http://example.com/config" + wfOwner = []byte("0xOwner") + + fetcher = newMockFetcher(map[string]mockFetchResp{ + binaryURL: {Body: binary, Err: nil}, + configURL: {Body: config, Err: nil}, + secretsURL: {Body: []byte("secrets"), Err: nil}, + }) + ) + + giveWFID := workflowID(binary, config, []byte(secretsURL)) + + b, err := hex.DecodeString(giveWFID) + require.NoError(t, err) + wfID := make([]byte, 32) + copy(wfID, b) + + active := WorkflowRegistryWorkflowRegisteredV1{ + Status: uint8(0), + WorkflowID: [32]byte(wfID), + WorkflowOwner: wfOwner, + WorkflowName: "workflow-name", + BinaryURL: binaryURL, + ConfigURL: configURL, + SecretsURL: secretsURL, + } + + er := newEngineRegistry() + store := wfstore.NewDBStore(db, lggr, clockwork.NewFakeClock()) + registry := capabilities.NewRegistry(lggr) + h := &eventHandler{ + lggr: lggr, + orm: orm, + fetcher: fetcher, + emitter: emitter, + engineRegistry: er, + capRegistry: registry, + workflowStore: store, + } + err = h.workflowRegisteredEvent(ctx, active) + require.NoError(t, err) + + // Verify the record is updated in the database + dbSpec, err := orm.GetWorkflowSpec(ctx, hex.EncodeToString(wfOwner), "workflow-name") + require.NoError(t, err) + require.Equal(t, hex.EncodeToString(wfOwner), dbSpec.WorkflowOwner) + require.Equal(t, "workflow-name", dbSpec.WorkflowName) + require.Equal(t, job.WorkflowSpecStatusActive, dbSpec.Status) + + // Verify the engine is started + engine, err := h.engineRegistry.Get(giveWFID) + require.NoError(t, err) + err = engine.Ready() + require.NoError(t, err) + }) +} diff --git a/core/services/workflows/syncer/mocks/orm.go b/core/services/workflows/syncer/mocks/orm.go index 19c459fa0ee..128100ea907 100644 --- a/core/services/workflows/syncer/mocks/orm.go +++ b/core/services/workflows/syncer/mocks/orm.go @@ -81,59 +81,50 @@ func (_c *ORM_Create_Call) RunAndReturn(run func(context.Context, string, string return _c } -// CreateWorkflowSpec provides a mock function with given fields: ctx, spec -func (_m *ORM) CreateWorkflowSpec(ctx context.Context, spec *job.WorkflowSpec) (int64, error) { - ret := _m.Called(ctx, spec) +// DeleteWorkflowSpec provides a mock function with given fields: ctx, owner, name +func (_m *ORM) DeleteWorkflowSpec(ctx context.Context, owner string, name string) error { + ret := _m.Called(ctx, owner, name) if len(ret) == 0 { - panic("no return value specified for CreateWorkflowSpec") + panic("no return value specified for DeleteWorkflowSpec") } - var r0 int64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *job.WorkflowSpec) (int64, error)); ok { - return rf(ctx, spec) - } - if rf, ok := ret.Get(0).(func(context.Context, *job.WorkflowSpec) int64); ok { - r0 = rf(ctx, spec) + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { + r0 = rf(ctx, owner, name) } else { - r0 = ret.Get(0).(int64) + r0 = ret.Error(0) } - if rf, ok := ret.Get(1).(func(context.Context, *job.WorkflowSpec) error); ok { - r1 = rf(ctx, spec) - } else { - r1 = ret.Error(1) - } - - return r0, r1 + return r0 } -// ORM_CreateWorkflowSpec_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateWorkflowSpec' -type ORM_CreateWorkflowSpec_Call struct { +// ORM_DeleteWorkflowSpec_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteWorkflowSpec' +type ORM_DeleteWorkflowSpec_Call struct { *mock.Call } -// CreateWorkflowSpec is a helper method to define mock.On call +// DeleteWorkflowSpec is a helper method to define mock.On call // - ctx context.Context -// - spec *job.WorkflowSpec -func (_e *ORM_Expecter) CreateWorkflowSpec(ctx interface{}, spec interface{}) *ORM_CreateWorkflowSpec_Call { - return &ORM_CreateWorkflowSpec_Call{Call: _e.mock.On("CreateWorkflowSpec", ctx, spec)} +// - owner string +// - name string +func (_e *ORM_Expecter) DeleteWorkflowSpec(ctx interface{}, owner interface{}, name interface{}) *ORM_DeleteWorkflowSpec_Call { + return &ORM_DeleteWorkflowSpec_Call{Call: _e.mock.On("DeleteWorkflowSpec", ctx, owner, name)} } -func (_c *ORM_CreateWorkflowSpec_Call) Run(run func(ctx context.Context, spec *job.WorkflowSpec)) *ORM_CreateWorkflowSpec_Call { +func (_c *ORM_DeleteWorkflowSpec_Call) Run(run func(ctx context.Context, owner string, name string)) *ORM_DeleteWorkflowSpec_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*job.WorkflowSpec)) + run(args[0].(context.Context), args[1].(string), args[2].(string)) }) return _c } -func (_c *ORM_CreateWorkflowSpec_Call) Return(_a0 int64, _a1 error) *ORM_CreateWorkflowSpec_Call { - _c.Call.Return(_a0, _a1) +func (_c *ORM_DeleteWorkflowSpec_Call) Return(_a0 error) *ORM_DeleteWorkflowSpec_Call { + _c.Call.Return(_a0) return _c } -func (_c *ORM_CreateWorkflowSpec_Call) RunAndReturn(run func(context.Context, *job.WorkflowSpec) (int64, error)) *ORM_CreateWorkflowSpec_Call { +func (_c *ORM_DeleteWorkflowSpec_Call) RunAndReturn(run func(context.Context, string, string) error) *ORM_DeleteWorkflowSpec_Call { _c.Call.Return(run) return _c } @@ -425,6 +416,66 @@ func (_c *ORM_GetSecretsURLHash_Call) RunAndReturn(run func([]byte, []byte) ([]b return _c } +// GetWorkflowSpec provides a mock function with given fields: ctx, owner, name +func (_m *ORM) GetWorkflowSpec(ctx context.Context, owner string, name string) (*job.WorkflowSpec, error) { + ret := _m.Called(ctx, owner, name) + + if len(ret) == 0 { + panic("no return value specified for GetWorkflowSpec") + } + + var r0 *job.WorkflowSpec + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, string) (*job.WorkflowSpec, error)); ok { + return rf(ctx, owner, name) + } + if rf, ok := ret.Get(0).(func(context.Context, string, string) *job.WorkflowSpec); ok { + r0 = rf(ctx, owner, name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*job.WorkflowSpec) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { + r1 = rf(ctx, owner, name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ORM_GetWorkflowSpec_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetWorkflowSpec' +type ORM_GetWorkflowSpec_Call struct { + *mock.Call +} + +// GetWorkflowSpec is a helper method to define mock.On call +// - ctx context.Context +// - owner string +// - name string +func (_e *ORM_Expecter) GetWorkflowSpec(ctx interface{}, owner interface{}, name interface{}) *ORM_GetWorkflowSpec_Call { + return &ORM_GetWorkflowSpec_Call{Call: _e.mock.On("GetWorkflowSpec", ctx, owner, name)} +} + +func (_c *ORM_GetWorkflowSpec_Call) Run(run func(ctx context.Context, owner string, name string)) *ORM_GetWorkflowSpec_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string), args[2].(string)) + }) + return _c +} + +func (_c *ORM_GetWorkflowSpec_Call) Return(_a0 *job.WorkflowSpec, _a1 error) *ORM_GetWorkflowSpec_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ORM_GetWorkflowSpec_Call) RunAndReturn(run func(context.Context, string, string) (*job.WorkflowSpec, error)) *ORM_GetWorkflowSpec_Call { + _c.Call.Return(run) + return _c +} + // Update provides a mock function with given fields: ctx, secretsURL, contents func (_m *ORM) Update(ctx context.Context, secretsURL string, contents string) (int64, error) { ret := _m.Called(ctx, secretsURL, contents) @@ -483,6 +534,123 @@ func (_c *ORM_Update_Call) RunAndReturn(run func(context.Context, string, string return _c } +// UpsertWorkflowSpec provides a mock function with given fields: ctx, spec +func (_m *ORM) UpsertWorkflowSpec(ctx context.Context, spec *job.WorkflowSpec) (int64, error) { + ret := _m.Called(ctx, spec) + + if len(ret) == 0 { + panic("no return value specified for UpsertWorkflowSpec") + } + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *job.WorkflowSpec) (int64, error)); ok { + return rf(ctx, spec) + } + if rf, ok := ret.Get(0).(func(context.Context, *job.WorkflowSpec) int64); ok { + r0 = rf(ctx, spec) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, *job.WorkflowSpec) error); ok { + r1 = rf(ctx, spec) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ORM_UpsertWorkflowSpec_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpsertWorkflowSpec' +type ORM_UpsertWorkflowSpec_Call struct { + *mock.Call +} + +// UpsertWorkflowSpec is a helper method to define mock.On call +// - ctx context.Context +// - spec *job.WorkflowSpec +func (_e *ORM_Expecter) UpsertWorkflowSpec(ctx interface{}, spec interface{}) *ORM_UpsertWorkflowSpec_Call { + return &ORM_UpsertWorkflowSpec_Call{Call: _e.mock.On("UpsertWorkflowSpec", ctx, spec)} +} + +func (_c *ORM_UpsertWorkflowSpec_Call) Run(run func(ctx context.Context, spec *job.WorkflowSpec)) *ORM_UpsertWorkflowSpec_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*job.WorkflowSpec)) + }) + return _c +} + +func (_c *ORM_UpsertWorkflowSpec_Call) Return(_a0 int64, _a1 error) *ORM_UpsertWorkflowSpec_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ORM_UpsertWorkflowSpec_Call) RunAndReturn(run func(context.Context, *job.WorkflowSpec) (int64, error)) *ORM_UpsertWorkflowSpec_Call { + _c.Call.Return(run) + return _c +} + +// UpsertWorkflowSpecWithSecrets provides a mock function with given fields: ctx, spec, url, hash, contents +func (_m *ORM) UpsertWorkflowSpecWithSecrets(ctx context.Context, spec *job.WorkflowSpec, url string, hash string, contents string) (int64, error) { + ret := _m.Called(ctx, spec, url, hash, contents) + + if len(ret) == 0 { + panic("no return value specified for UpsertWorkflowSpecWithSecrets") + } + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *job.WorkflowSpec, string, string, string) (int64, error)); ok { + return rf(ctx, spec, url, hash, contents) + } + if rf, ok := ret.Get(0).(func(context.Context, *job.WorkflowSpec, string, string, string) int64); ok { + r0 = rf(ctx, spec, url, hash, contents) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, *job.WorkflowSpec, string, string, string) error); ok { + r1 = rf(ctx, spec, url, hash, contents) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ORM_UpsertWorkflowSpecWithSecrets_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpsertWorkflowSpecWithSecrets' +type ORM_UpsertWorkflowSpecWithSecrets_Call struct { + *mock.Call +} + +// UpsertWorkflowSpecWithSecrets is a helper method to define mock.On call +// - ctx context.Context +// - spec *job.WorkflowSpec +// - url string +// - hash string +// - contents string +func (_e *ORM_Expecter) UpsertWorkflowSpecWithSecrets(ctx interface{}, spec interface{}, url interface{}, hash interface{}, contents interface{}) *ORM_UpsertWorkflowSpecWithSecrets_Call { + return &ORM_UpsertWorkflowSpecWithSecrets_Call{Call: _e.mock.On("UpsertWorkflowSpecWithSecrets", ctx, spec, url, hash, contents)} +} + +func (_c *ORM_UpsertWorkflowSpecWithSecrets_Call) Run(run func(ctx context.Context, spec *job.WorkflowSpec, url string, hash string, contents string)) *ORM_UpsertWorkflowSpecWithSecrets_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*job.WorkflowSpec), args[2].(string), args[3].(string), args[4].(string)) + }) + return _c +} + +func (_c *ORM_UpsertWorkflowSpecWithSecrets_Call) Return(_a0 int64, _a1 error) *ORM_UpsertWorkflowSpecWithSecrets_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ORM_UpsertWorkflowSpecWithSecrets_Call) RunAndReturn(run func(context.Context, *job.WorkflowSpec, string, string, string) (int64, error)) *ORM_UpsertWorkflowSpecWithSecrets_Call { + _c.Call.Return(run) + return _c +} + // NewORM creates a new instance of ORM. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewORM(t interface { diff --git a/core/services/workflows/syncer/orm.go b/core/services/workflows/syncer/orm.go index d43dbe09b78..16612b9a9c6 100644 --- a/core/services/workflows/syncer/orm.go +++ b/core/services/workflows/syncer/orm.go @@ -2,7 +2,9 @@ package syncer import ( "context" - "errors" + "database/sql" + "fmt" + "time" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -33,7 +35,19 @@ type WorkflowSecretsDS interface { } type WorkflowSpecsDS interface { - CreateWorkflowSpec(ctx context.Context, spec *job.WorkflowSpec) (int64, error) + // UpsertWorkflowSpec inserts or updates a workflow spec. Updates on conflict of workflow name + // and owner + UpsertWorkflowSpec(ctx context.Context, spec *job.WorkflowSpec) (int64, error) + + // UpsertWorkflowSpecWithSecrets inserts or updates a workflow spec with secrets in a transaction. + // Updates on conflict of workflow name and owner. + UpsertWorkflowSpecWithSecrets(ctx context.Context, spec *job.WorkflowSpec, url, hash, contents string) (int64, error) + + // GetWorkflowSpec returns the workflow spec for the given owner and name. + GetWorkflowSpec(ctx context.Context, owner, name string) (*job.WorkflowSpec, error) + + // DeleteWorkflowSpec deletes the workflow spec for the given owner and name. + DeleteWorkflowSpec(ctx context.Context, owner, name string) error } type ORM interface { @@ -149,6 +163,179 @@ func (orm *orm) GetSecretsURLHash(owner, secretsURL []byte) ([]byte, error) { return crypto.Keccak256(append(owner, secretsURL...)) } -func (orm *orm) CreateWorkflowSpec(ctx context.Context, spec *job.WorkflowSpec) (int64, error) { - return 0, errors.New("not implemented") +func (orm *orm) UpsertWorkflowSpec(ctx context.Context, spec *job.WorkflowSpec) (int64, error) { + var id int64 + + query := ` + INSERT INTO workflow_specs ( + workflow, + config, + workflow_id, + workflow_owner, + workflow_name, + status, + binary_url, + config_url, + secrets_id, + created_at, + updated_at, + spec_type + ) VALUES ( + :workflow, + :config, + :workflow_id, + :workflow_owner, + :workflow_name, + :status, + :binary_url, + :config_url, + :secrets_id, + :created_at, + :updated_at, + :spec_type + ) ON CONFLICT (workflow_owner, workflow_name) DO UPDATE + SET + workflow = EXCLUDED.workflow, + config = EXCLUDED.config, + workflow_id = EXCLUDED.workflow_id, + workflow_owner = EXCLUDED.workflow_owner, + workflow_name = EXCLUDED.workflow_name, + status = EXCLUDED.status, + binary_url = EXCLUDED.binary_url, + config_url = EXCLUDED.config_url, + secrets_id = EXCLUDED.secrets_id, + created_at = EXCLUDED.created_at, + updated_at = EXCLUDED.updated_at, + spec_type = EXCLUDED.spec_type + RETURNING id + ` + + stmt, err := orm.ds.PrepareNamedContext(ctx, query) + if err != nil { + return 0, err + } + defer stmt.Close() + + spec.UpdatedAt = time.Now() + err = stmt.QueryRowxContext(ctx, spec).Scan(&id) + + if err != nil { + return 0, err + } + + return id, nil +} + +func (orm *orm) UpsertWorkflowSpecWithSecrets( + ctx context.Context, + spec *job.WorkflowSpec, url, hash, contents string) (int64, error) { + var id int64 + err := sqlutil.TransactDataSource(ctx, orm.ds, nil, func(tx sqlutil.DataSource) error { + var sid int64 + txErr := tx.QueryRowxContext(ctx, + `INSERT INTO workflow_secrets (secrets_url, secrets_url_hash, contents) + VALUES ($1, $2, $3) + RETURNING id`, + url, hash, contents, + ).Scan(&sid) + + if txErr != nil { + return fmt.Errorf("failed to create workflow secrets: %w", txErr) + } + + spec.SecretsID = sql.NullInt64{Int64: sid, Valid: true} + + query := ` + INSERT INTO workflow_specs ( + workflow, + config, + workflow_id, + workflow_owner, + workflow_name, + status, + binary_url, + config_url, + secrets_id, + created_at, + updated_at, + spec_type + ) VALUES ( + :workflow, + :config, + :workflow_id, + :workflow_owner, + :workflow_name, + :status, + :binary_url, + :config_url, + :secrets_id, + :created_at, + :updated_at, + :spec_type + ) ON CONFLICT (workflow_owner, workflow_name) DO UPDATE + SET + workflow = EXCLUDED.workflow, + config = EXCLUDED.config, + workflow_id = EXCLUDED.workflow_id, + workflow_owner = EXCLUDED.workflow_owner, + workflow_name = EXCLUDED.workflow_name, + status = EXCLUDED.status, + binary_url = EXCLUDED.binary_url, + config_url = EXCLUDED.config_url, + secrets_id = EXCLUDED.secrets_id, + created_at = EXCLUDED.created_at, + updated_at = EXCLUDED.updated_at, + spec_type = EXCLUDED.spec_type + RETURNING id + ` + + stmt, txErr := tx.PrepareNamedContext(ctx, query) + if txErr != nil { + return txErr + } + defer stmt.Close() + + spec.UpdatedAt = time.Now() + return stmt.QueryRowxContext(ctx, spec).Scan(&id) + }) + return id, err +} + +func (orm *orm) GetWorkflowSpec(ctx context.Context, owner, name string) (*job.WorkflowSpec, error) { + query := ` + SELECT * + FROM workflow_specs + WHERE workflow_owner = $1 AND workflow_name = $2 + ` + + var spec job.WorkflowSpec + err := orm.ds.GetContext(ctx, &spec, query, owner, name) + if err != nil { + return nil, err + } + + return &spec, nil +} + +func (orm *orm) DeleteWorkflowSpec(ctx context.Context, owner, name string) error { + query := ` + DELETE FROM workflow_specs + WHERE workflow_owner = $1 AND workflow_name = $2 + ` + + result, err := orm.ds.ExecContext(ctx, query, owner, name) + if err != nil { + return err + } + + rowsAffected, err := result.RowsAffected() + if err != nil { + return err + } + + if rowsAffected == 0 { + return sql.ErrNoRows // No spec deleted + } + + return nil } diff --git a/core/services/workflows/syncer/orm_test.go b/core/services/workflows/syncer/orm_test.go index 8b9f685bb52..1be4e54f472 100644 --- a/core/services/workflows/syncer/orm_test.go +++ b/core/services/workflows/syncer/orm_test.go @@ -1,12 +1,15 @@ package syncer import ( + "database/sql" "encoding/hex" "testing" + "time" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" "github.com/stretchr/testify/assert" @@ -51,3 +54,145 @@ func TestWorkflowArtifactsORM_GetAndUpdate(t *testing.T) { require.NoError(t, err) assert.Equal(t, "new contents", contents) } + +func Test_UpsertWorkflowSpec(t *testing.T) { + db := pgtest.NewSqlxDB(t) + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + orm := &orm{ds: db, lggr: lggr} + + t.Run("inserts new spec", func(t *testing.T) { + spec := &job.WorkflowSpec{ + Workflow: "test_workflow", + Config: "test_config", + WorkflowID: "cid-123", + WorkflowOwner: "owner-123", + WorkflowName: "Test Workflow", + Status: job.WorkflowSpecStatusActive, + BinaryURL: "http://example.com/binary", + ConfigURL: "http://example.com/config", + CreatedAt: time.Now(), + SpecType: job.WASMFile, + } + + _, err := orm.UpsertWorkflowSpec(ctx, spec) + require.NoError(t, err) + + // Verify the record exists in the database + var dbSpec job.WorkflowSpec + err = db.Get(&dbSpec, `SELECT * FROM workflow_specs WHERE workflow_owner = $1 AND workflow_name = $2`, spec.WorkflowOwner, spec.WorkflowName) + require.NoError(t, err) + require.Equal(t, spec.Workflow, dbSpec.Workflow) + }) + + t.Run("updates existing spec", func(t *testing.T) { + spec := &job.WorkflowSpec{ + Workflow: "test_workflow", + Config: "test_config", + WorkflowID: "cid-123", + WorkflowOwner: "owner-123", + WorkflowName: "Test Workflow", + Status: job.WorkflowSpecStatusActive, + BinaryURL: "http://example.com/binary", + ConfigURL: "http://example.com/config", + CreatedAt: time.Now(), + SpecType: job.WASMFile, + } + + _, err := orm.UpsertWorkflowSpec(ctx, spec) + require.NoError(t, err) + + // Update the status + spec.Status = job.WorkflowSpecStatusPaused + + _, err = orm.UpsertWorkflowSpec(ctx, spec) + require.NoError(t, err) + + // Verify the record is updated in the database + var dbSpec job.WorkflowSpec + err = db.Get(&dbSpec, `SELECT * FROM workflow_specs WHERE workflow_owner = $1 AND workflow_name = $2`, spec.WorkflowOwner, spec.WorkflowName) + require.NoError(t, err) + require.Equal(t, spec.Config, dbSpec.Config) + require.Equal(t, spec.Status, dbSpec.Status) + }) +} + +func Test_DeleteWorkflowSpec(t *testing.T) { + db := pgtest.NewSqlxDB(t) + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + orm := &orm{ds: db, lggr: lggr} + + t.Run("deletes a workflow spec", func(t *testing.T) { + spec := &job.WorkflowSpec{ + Workflow: "test_workflow", + Config: "test_config", + WorkflowID: "cid-123", + WorkflowOwner: "owner-123", + WorkflowName: "Test Workflow", + Status: job.WorkflowSpecStatusActive, + BinaryURL: "http://example.com/binary", + ConfigURL: "http://example.com/config", + CreatedAt: time.Now(), + SpecType: job.WASMFile, + } + + id, err := orm.UpsertWorkflowSpec(ctx, spec) + require.NoError(t, err) + require.NotZero(t, id) + + err = orm.DeleteWorkflowSpec(ctx, spec.WorkflowOwner, spec.WorkflowName) + require.NoError(t, err) + + // Verify the record is deleted from the database + var dbSpec job.WorkflowSpec + err = db.Get(&dbSpec, `SELECT * FROM workflow_specs WHERE id = $1`, id) + require.Error(t, err) + require.Equal(t, sql.ErrNoRows, err) + }) + + t.Run("fails if no workflow spec exists", func(t *testing.T) { + err := orm.DeleteWorkflowSpec(ctx, "owner-123", "Test Workflow") + require.Error(t, err) + require.Equal(t, sql.ErrNoRows, err) + }) +} + +func Test_GetWorkflowSpec(t *testing.T) { + db := pgtest.NewSqlxDB(t) + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + orm := &orm{ds: db, lggr: lggr} + + t.Run("gets a workflow spec", func(t *testing.T) { + spec := &job.WorkflowSpec{ + Workflow: "test_workflow", + Config: "test_config", + WorkflowID: "cid-123", + WorkflowOwner: "owner-123", + WorkflowName: "Test Workflow", + Status: job.WorkflowSpecStatusActive, + BinaryURL: "http://example.com/binary", + ConfigURL: "http://example.com/config", + CreatedAt: time.Now(), + SpecType: job.WASMFile, + } + + id, err := orm.UpsertWorkflowSpec(ctx, spec) + require.NoError(t, err) + require.NotZero(t, id) + + dbSpec, err := orm.GetWorkflowSpec(ctx, spec.WorkflowOwner, spec.WorkflowName) + require.NoError(t, err) + require.Equal(t, spec.Workflow, dbSpec.Workflow) + + err = orm.DeleteWorkflowSpec(ctx, spec.WorkflowOwner, spec.WorkflowName) + require.NoError(t, err) + }) + + t.Run("fails if no workflow spec exists", func(t *testing.T) { + dbSpec, err := orm.GetWorkflowSpec(ctx, "owner-123", "Test Workflow") + require.Error(t, err) + require.Nil(t, dbSpec) + }) +} diff --git a/core/services/workflows/syncer/workflow_registry.go b/core/services/workflows/syncer/workflow_registry.go index d8ad37646d6..cdd0c71acc0 100644 --- a/core/services/workflows/syncer/workflow_registry.go +++ b/core/services/workflows/syncer/workflow_registry.go @@ -10,6 +10,7 @@ import ( "sync" "time" + "github.com/smartcontractkit/chainlink-common/pkg/custmsg" "github.com/smartcontractkit/chainlink-common/pkg/services" types "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/core" @@ -95,6 +96,7 @@ type workflowRegistry struct { ticker <-chan time.Time lggr logger.Logger + emitter custmsg.Labeler orm WorkflowRegistryDS reader ContractReader gateway FetcherFunc @@ -147,11 +149,13 @@ func NewWorkflowRegistry[T ContractReader]( addr string, workflowStore store.Store, capRegistry core.CapabilitiesRegistry, + emitter custmsg.Labeler, opts ...func(*workflowRegistry), ) *workflowRegistry { ets := []WorkflowRegistryEventType{ForceUpdateSecretsEvent} wr := &workflowRegistry{ lggr: lggr.Named(name), + emitter: emitter, orm: orm, reader: reader, gateway: gateway, @@ -172,7 +176,7 @@ func NewWorkflowRegistry[T ContractReader]( batchCh: make(chan []WorkflowRegistryEventResponse, len(ets)), } wr.handler = newEventHandler(wr.lggr, wr.orm, wr.gateway, wr.workflowStore, wr.capRegistry, - wr.engineRegistry, + wr.engineRegistry, wr.emitter, secretsFetcherFunc(wr.SecretsFor), ) for _, opt := range opts { opt(wr) diff --git a/core/services/workflows/syncer/workflow_registry_test.go b/core/services/workflows/syncer/workflow_registry_test.go index 652b20deea1..58dcbed1022 100644 --- a/core/services/workflows/syncer/workflow_registry_test.go +++ b/core/services/workflows/syncer/workflow_registry_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/smartcontractkit/chainlink-common/pkg/custmsg" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" types "github.com/smartcontractkit/chainlink-common/pkg/types" query "github.com/smartcontractkit/chainlink-common/pkg/types/query" @@ -51,11 +52,12 @@ func Test_Workflow_Registry_Syncer(t *testing.T) { orm = &orm{ds: db, lggr: lggr} ctx, cancel = context.WithCancel(testutils.Context(t)) reader = NewMockContractReader(t) + emitter = custmsg.NewLabeler() gateway = func(_ context.Context, _ string) ([]byte, error) { return []byte(wantContents), nil } ticker = make(chan time.Time) - worker = NewWorkflowRegistry(lggr, orm, reader, gateway, giveCfg.ContractAddress, nil, nil, WithTicker(ticker)) + worker = NewWorkflowRegistry(lggr, orm, reader, gateway, giveCfg.ContractAddress, nil, nil, emitter, WithTicker(ticker)) ) // Cleanup the worker diff --git a/core/services/workflows/test/break/cmd/main.go b/core/services/workflows/test/break/cmd/main.go index 498d3b7b906..bf759f516c9 100644 --- a/core/services/workflows/test/break/cmd/main.go +++ b/core/services/workflows/test/break/cmd/main.go @@ -10,12 +10,7 @@ import ( ) func BuildWorkflow(config []byte) *sdk.WorkflowSpecFactory { - workflow := sdk.NewWorkflowSpecFactory( - sdk.NewWorkflowParams{ - Name: "tester", - Owner: "ryan", - }, - ) + workflow := sdk.NewWorkflowSpecFactory() triggerCfg := basictrigger.TriggerConfig{Name: "trigger", Number: 100} trigger := triggerCfg.New(workflow) diff --git a/core/services/workflows/test/wasm/cmd/main.go b/core/services/workflows/test/wasm/cmd/main.go index e496ab6ffa6..ed077365bcf 100644 --- a/core/services/workflows/test/wasm/cmd/main.go +++ b/core/services/workflows/test/wasm/cmd/main.go @@ -10,12 +10,7 @@ import ( ) func BuildWorkflow(config []byte) *sdk.WorkflowSpecFactory { - workflow := sdk.NewWorkflowSpecFactory( - sdk.NewWorkflowParams{ - Name: "tester", - Owner: "ryan", - }, - ) + workflow := sdk.NewWorkflowSpecFactory() triggerCfg := basictrigger.TriggerConfig{Name: "trigger", Number: 100} trigger := triggerCfg.New(workflow) diff --git a/core/store/migrate/migrations/0260_add_status_workflow_spec.sql b/core/store/migrate/migrations/0260_add_status_workflow_spec.sql new file mode 100644 index 00000000000..66c38eef2f7 --- /dev/null +++ b/core/store/migrate/migrations/0260_add_status_workflow_spec.sql @@ -0,0 +1,9 @@ +-- +goose Up +-- Add a `status` column to the `workflow_specs` table. +ALTER TABLE workflow_specs +ADD COLUMN status TEXT DEFAULT '' NOT NULL; + +-- +goose Down +-- Remove the `status` column from the `workflow_specs` table. +ALTER TABLE workflow_specs +DROP COLUMN status; \ No newline at end of file diff --git a/deployment/address_book.go b/deployment/address_book.go index 5a99216dda0..3125313a841 100644 --- a/deployment/address_book.go +++ b/deployment/address_book.go @@ -93,21 +93,26 @@ type AddressBookMap struct { mtx sync.RWMutex } -// save will save an address for a given chain selector. It will error if there is a conflicting existing address. +// Save will save an address for a given chain selector. It will error if there is a conflicting existing address. func (m *AddressBookMap) save(chainSelector uint64, address string, typeAndVersion TypeAndVersion) error { - _, exists := chainsel.ChainBySelector(chainSelector) - if !exists { + family, err := chainsel.GetSelectorFamily(chainSelector) + if err != nil { return errors.Wrapf(ErrInvalidChainSelector, "chain selector %d", chainSelector) } - if address == "" || address == common.HexToAddress("0x0").Hex() { - return errors.Wrap(ErrInvalidAddress, "address cannot be empty") - } - if common.IsHexAddress(address) { - // IMPORTANT: WE ALWAYS STANDARDIZE ETHEREUM ADDRESS STRINGS TO EIP55 - address = common.HexToAddress(address).Hex() - } else { - return errors.Wrapf(ErrInvalidAddress, "address %s is not a valid Ethereum address, only Ethereum addresses supported", address) + if family == chainsel.FamilyEVM { + if address == "" || address == common.HexToAddress("0x0").Hex() { + return errors.Wrap(ErrInvalidAddress, "address cannot be empty") + } + if common.IsHexAddress(address) { + // IMPORTANT: WE ALWAYS STANDARDIZE ETHEREUM ADDRESS STRINGS TO EIP55 + address = common.HexToAddress(address).Hex() + } else { + return errors.Wrapf(ErrInvalidAddress, "address %s is not a valid Ethereum address, only Ethereum addresses supported for EVM chains", address) + } } + + // TODO NONEVM-960: Add validation for non-EVM chain addresses + if typeAndVersion.Type == "" { return fmt.Errorf("type cannot be empty") } @@ -142,8 +147,8 @@ func (m *AddressBookMap) Addresses() (map[uint64]map[string]TypeAndVersion, erro } func (m *AddressBookMap) AddressesForChain(chainSelector uint64) (map[string]TypeAndVersion, error) { - _, exists := chainsel.ChainBySelector(chainSelector) - if !exists { + _, err := chainsel.GetChainIDFromSelector(chainSelector) + if err != nil { return nil, errors.Wrapf(ErrInvalidChainSelector, "chain selector %d", chainSelector) } diff --git a/deployment/address_book_test.go b/deployment/address_book_test.go index 47eb507e126..35efdbf8546 100644 --- a/deployment/address_book_test.go +++ b/deployment/address_book_test.go @@ -44,6 +44,10 @@ func TestAddressBook_Save(t *testing.T) { err = ab.Save(chainsel.TEST_90000001.Selector, common.HexToAddress("0x0").Hex(), onRamp100) require.Error(t, err) + // Zero address but non evm chain + err = NewMemoryAddressBook().Save(chainsel.APTOS_MAINNET.Selector, common.HexToAddress("0x0").Hex(), onRamp100) + require.NoError(t, err) + // Distinct address same TV will not err = ab.Save(chainsel.TEST_90000001.Selector, addr2, onRamp100) require.NoError(t, err) diff --git a/deployment/ccip/changeset/active_candidate.go b/deployment/ccip/changeset/active_candidate.go index a336cf69536..ee0c4d10ebf 100644 --- a/deployment/ccip/changeset/active_candidate.go +++ b/deployment/ccip/changeset/active_candidate.go @@ -52,15 +52,20 @@ func SetCandidatePluginChangeset( tokenConfig TokenConfig, pluginType cctypes.PluginType, ) (deployment.ChangesetOutput, error) { + ccipOCRParams := DefaultOCRParams( + feedChainSel, + tokenConfig.GetTokenInfo(e.Logger, state.Chains[newChainSel].LinkToken, state.Chains[newChainSel].Weth9), + nil, + ) newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome( ocrSecrets, state.Chains[newChainSel].OffRamp, e.Chains[newChainSel], - feedChainSel, - tokenConfig.GetTokenInfo(e.Logger, state.Chains[newChainSel].LinkToken, state.Chains[newChainSel].Weth9), nodes.NonBootstraps(), state.Chains[homeChainSel].RMNHome.Address(), - nil, + ccipOCRParams.OCRParameters, + ccipOCRParams.CommitOffChainConfig, + ccipOCRParams.ExecuteOffChainConfig, ) if err != nil { return deployment.ChangesetOutput{}, err diff --git a/deployment/ccip/changeset/active_candidate_test.go b/deployment/ccip/changeset/active_candidate_test.go index e53d3d177ad..40c0240f3db 100644 --- a/deployment/ccip/changeset/active_candidate_test.go +++ b/deployment/ccip/changeset/active_candidate_test.go @@ -123,15 +123,20 @@ func TestActiveCandidate(t *testing.T) { // commit and exec plugin we will be using rmnHomeAddress := state.Chains[tenv.HomeChainSel].RMNHome.Address() tokenConfig := NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds) + ccipOCRParams := DefaultOCRParams( + tenv.FeedChainSel, + tokenConfig.GetTokenInfo(e.Logger, state.Chains[tenv.FeedChainSel].LinkToken, state.Chains[tenv.FeedChainSel].Weth9), + nil, + ) ocr3ConfigMap, err := internal.BuildOCR3ConfigForCCIPHome( deployment.XXXGenerateTestOCRSecrets(), state.Chains[tenv.FeedChainSel].OffRamp, e.Chains[tenv.FeedChainSel], - tenv.FeedChainSel, - tokenConfig.GetTokenInfo(e.Logger, state.Chains[tenv.FeedChainSel].LinkToken, state.Chains[tenv.FeedChainSel].Weth9), nodes.NonBootstraps(), rmnHomeAddress, - nil, + ccipOCRParams.OCRParameters, + ccipOCRParams.CommitOffChainConfig, + ccipOCRParams.ExecuteOffChainConfig, ) require.NoError(t, err) diff --git a/deployment/ccip/changeset/add_chain.go b/deployment/ccip/changeset/add_chain.go index cb7d0701973..bc4d8d6b97e 100644 --- a/deployment/ccip/changeset/add_chain.go +++ b/deployment/ccip/changeset/add_chain.go @@ -98,15 +98,20 @@ func AddDonAndSetCandidateChangeset( tokenConfig TokenConfig, pluginType types.PluginType, ) (deployment.ChangesetOutput, error) { + ccipOCRParams := DefaultOCRParams( + feedChainSel, + tokenConfig.GetTokenInfo(e.Logger, state.Chains[newChainSel].LinkToken, state.Chains[newChainSel].Weth9), + nil, + ) newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome( ocrSecrets, state.Chains[newChainSel].OffRamp, e.Chains[newChainSel], - feedChainSel, - tokenConfig.GetTokenInfo(e.Logger, state.Chains[newChainSel].LinkToken, state.Chains[newChainSel].Weth9), nodes.NonBootstraps(), state.Chains[homeChainSel].RMNHome.Address(), - nil, + ccipOCRParams.OCRParameters, + ccipOCRParams.CommitOffChainConfig, + ccipOCRParams.ExecuteOffChainConfig, ) if err != nil { return deployment.ChangesetOutput{}, err diff --git a/deployment/ccip/changeset/add_chain_test.go b/deployment/ccip/changeset/add_chain_test.go index 81f9d2412ec..7b5ae9c43d7 100644 --- a/deployment/ccip/changeset/add_chain_test.go +++ b/deployment/ccip/changeset/add_chain_test.go @@ -59,12 +59,17 @@ func TestAddChainInbound(t *testing.T) { require.NoError(t, e.Env.ExistingAddresses.Merge(out.AddressBook)) newAddresses = deployment.NewMemoryAddressBook() tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) + ocrParams := make(map[uint64]CCIPOCRParams) + for _, chain := range initialDeploy { + ocrParams[chain] = DefaultOCRParams(e.FeedChainSel, nil, nil) + } err = deployCCIPContracts(e.Env, newAddresses, NewChainsConfig{ HomeChainSel: e.HomeChainSel, FeedChainSel: e.FeedChainSel, ChainsToDeploy: initialDeploy, TokenConfig: tokenConfig, OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), + OCRParams: ocrParams, }) require.NoError(t, err) @@ -75,7 +80,7 @@ func TestAddChainInbound(t *testing.T) { for _, source := range initialDeploy { for _, dest := range initialDeploy { if source != dest { - require.NoError(t, AddLaneWithDefaultPrices(e.Env, state, source, dest)) + require.NoError(t, AddLaneWithDefaultPricesAndFeeQuoterConfig(e.Env, state, source, dest, false)) } } } diff --git a/deployment/ccip/changeset/add_lane.go b/deployment/ccip/changeset/add_lane.go index 82cf60b77f6..0b16611021f 100644 --- a/deployment/ccip/changeset/add_lane.go +++ b/deployment/ccip/changeset/add_lane.go @@ -2,9 +2,11 @@ package changeset import ( "encoding/hex" + "fmt" "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccipevm" @@ -15,25 +17,122 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" ) +var _ deployment.ChangeSet[AddLanesConfig] = AddLanesWithTestRouter + type InitialPrices struct { LinkPrice *big.Int // USD to the power of 18 (e18) per LINK WethPrice *big.Int // USD to the power of 18 (e18) per WETH GasPrice *big.Int // uint224 packed gas price in USD (112 for exec // 112 for da) } +func (p InitialPrices) Validate() error { + if p.LinkPrice == nil { + return fmt.Errorf("missing link price") + } + if p.WethPrice == nil { + return fmt.Errorf("missing weth price") + } + if p.GasPrice == nil { + return fmt.Errorf("missing gas price") + } + return nil +} + +type LaneConfig struct { + SourceSelector uint64 + DestSelector uint64 + InitialPricesBySource InitialPrices + FeeQuoterDestChain fee_quoter.FeeQuoterDestChainConfig +} + +type AddLanesConfig struct { + LaneConfigs []LaneConfig +} + +func (c AddLanesConfig) Validate() error { + for _, pair := range c.LaneConfigs { + if pair.SourceSelector == pair.DestSelector { + return fmt.Errorf("cannot add lane to the same chain") + } + if err := pair.InitialPricesBySource.Validate(); err != nil { + return fmt.Errorf("error in validating initial prices for chain %d : %w", pair.SourceSelector, err) + } + // TODO: add more FeeQuoterDestChainConfigArgs validation + if pair.FeeQuoterDestChain == (fee_quoter.FeeQuoterDestChainConfig{}) { + return fmt.Errorf("missing fee quoter dest chain config") + } + } + return nil +} + +// AddLanesWithTestRouter adds lanes between chains using the test router. +// AddLanesWithTestRouter is run while the contracts are still owned by the deployer. +// This is useful to test the initial deployment to enable lanes between chains. +// Once the testrouter is enabled, the lanes can be used to send messages between chains with testrouter. +// On successful verification with testrouter, the lanes can be enabled with the main router with different AddLane ChangeSet. +func AddLanesWithTestRouter(e deployment.Environment, cfg AddLanesConfig) (deployment.ChangesetOutput, error) { + if err := cfg.Validate(); err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("invalid AddLanesConfig: %w", err) + } + newAddresses := deployment.NewMemoryAddressBook() + err := addLanes(e, cfg) + if err != nil { + e.Logger.Errorw("Failed to add lanes", "err", err) + return deployment.ChangesetOutput{}, err + } + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{}, + AddressBook: newAddresses, + JobSpecs: nil, + }, nil +} + var DefaultInitialPrices = InitialPrices{ LinkPrice: deployment.E18Mult(20), WethPrice: deployment.E18Mult(4000), GasPrice: ToPackedFee(big.NewInt(8e14), big.NewInt(0)), } -func AddLaneWithDefaultPrices(e deployment.Environment, state CCIPOnChainState, from, to uint64) error { - return AddLane(e, state, from, to, DefaultInitialPrices) +func addLanes(e deployment.Environment, cfg AddLanesConfig) error { + state, err := LoadOnchainState(e) + if err != nil { + return fmt.Errorf("failed to load onchain state: %w", err) + } + for _, laneCfg := range cfg.LaneConfigs { + e.Logger.Infow("Enabling lane with test router", "from", laneCfg.SourceSelector, "to", laneCfg.DestSelector) + if err := AddLane(e, state, laneCfg, true); err != nil { + return err + } + } + return nil } -func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64, initialPrices InitialPrices) error { +func AddLaneWithDefaultPricesAndFeeQuoterConfig(e deployment.Environment, state CCIPOnChainState, from, to uint64, isTestRouter bool) error { + cfg := LaneConfig{ + SourceSelector: from, + DestSelector: to, + InitialPricesBySource: DefaultInitialPrices, + FeeQuoterDestChain: DefaultFeeQuoterDestChainConfig(), + } + return AddLane(e, state, cfg, isTestRouter) +} + +func AddLane(e deployment.Environment, state CCIPOnChainState, config LaneConfig, isTestRouter bool) error { // TODO: Batch - tx, err := state.Chains[from].Router.ApplyRampUpdates(e.Chains[from].DeployerKey, []router.RouterOnRamp{ + var fromRouter *router.Router + var toRouter *router.Router + from := config.SourceSelector + to := config.DestSelector + feeQuoterDestChainConfig := config.FeeQuoterDestChain + initialPrices := config.InitialPricesBySource + if isTestRouter { + fromRouter = state.Chains[from].TestRouter + toRouter = state.Chains[to].TestRouter + } else { + fromRouter = state.Chains[from].Router + toRouter = state.Chains[to].Router + } + tx, err := fromRouter.ApplyRampUpdates(e.Chains[from].DeployerKey, []router.RouterOnRamp{ { DestChainSelector: to, OnRamp: state.Chains[from].OnRamp.Address(), @@ -46,7 +145,7 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64, []onramp.OnRampDestChainConfigArgs{ { DestChainSelector: to, - Router: state.Chains[from].Router.Address(), + Router: fromRouter.Address(), }, }) if _, err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { @@ -80,7 +179,7 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64, []fee_quoter.FeeQuoterDestChainConfigArgs{ { DestChainSelector: to, - DestChainConfig: DefaultFeeQuoterDestChainConfig(), + DestChainConfig: feeQuoterDestChainConfig, }, }) if _, err := deployment.ConfirmIfNoError(e.Chains[from], tx, err); err != nil { @@ -90,7 +189,7 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64, tx, err = state.Chains[to].OffRamp.ApplySourceChainConfigUpdates(e.Chains[to].DeployerKey, []offramp.OffRampSourceChainConfigArgs{ { - Router: state.Chains[to].Router.Address(), + Router: toRouter.Address(), SourceChainSelector: from, IsEnabled: true, OnRamp: common.LeftPadBytes(state.Chains[from].OnRamp.Address().Bytes(), 32), @@ -99,7 +198,7 @@ func AddLane(e deployment.Environment, state CCIPOnChainState, from, to uint64, if _, err := deployment.ConfirmIfNoError(e.Chains[to], tx, err); err != nil { return err } - tx, err = state.Chains[to].Router.ApplyRampUpdates(e.Chains[to].DeployerKey, []router.RouterOnRamp{}, []router.RouterOffRamp{}, []router.RouterOffRamp{ + tx, err = toRouter.ApplyRampUpdates(e.Chains[to].DeployerKey, []router.RouterOnRamp{}, []router.RouterOffRamp{}, []router.RouterOffRamp{ { SourceChainSelector: from, OffRamp: state.Chains[to].OffRamp.Address(), diff --git a/deployment/ccip/changeset/add_lane_test.go b/deployment/ccip/changeset/add_lane_test.go index 1939d0da10a..194777c07bc 100644 --- a/deployment/ccip/changeset/add_lane_test.go +++ b/deployment/ccip/changeset/add_lane_test.go @@ -16,6 +16,48 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" ) +func TestAddLanesWithTestRouter(t *testing.T) { + e := NewMemoryEnvironmentWithJobsAndContracts(t, logger.TestLogger(t), 2, 4, nil) + // Here we have CR + nodes set up, but no CCIP contracts deployed. + state, err := LoadOnchainState(e.Env) + require.NoError(t, err) + + selectors := e.Env.AllChainSelectors() + chain1, chain2 := selectors[0], selectors[1] + + _, err = AddLanesWithTestRouter(e.Env, AddLanesConfig{ + LaneConfigs: []LaneConfig{ + { + SourceSelector: chain1, + DestSelector: chain2, + InitialPricesBySource: DefaultInitialPrices, + FeeQuoterDestChain: DefaultFeeQuoterDestChainConfig(), + }, + }, + }) + require.NoError(t, err) + // Need to keep track of the block number for each chain so that event subscription can be done from that block. + startBlocks := make(map[uint64]*uint64) + // Send a message from each chain to every other chain. + expectedSeqNumExec := make(map[SourceDestPair][]uint64) + latesthdr, err := e.Env.Chains[chain2].Client.HeaderByNumber(testcontext.Get(t), nil) + require.NoError(t, err) + block := latesthdr.Number.Uint64() + startBlocks[chain2] = &block + msgSentEvent := TestSendRequest(t, e.Env, state, chain1, chain2, true, router.ClientEVM2AnyMessage{ + Receiver: common.LeftPadBytes(state.Chains[chain2].Receiver.Address().Bytes(), 32), + Data: []byte("hello"), + TokenAmounts: nil, + FeeToken: common.HexToAddress("0x0"), + ExtraArgs: nil, + }) + expectedSeqNumExec[SourceDestPair{ + SourceChainSelector: chain1, + DestChainSelector: chain2, + }] = []uint64{msgSentEvent.SequenceNumber} + ConfirmExecWithSeqNrsForAll(t, e.Env, state, expectedSeqNumExec, startBlocks) +} + // TestAddLane covers the workflow of adding a lane between two chains and enabling it. // It also covers the case where the onRamp is disabled on the OffRamp contract initially and then enabled. func TestAddLane(t *testing.T) { @@ -41,7 +83,7 @@ func TestAddLane(t *testing.T) { require.NoError(t, err) // Add one lane from chain1 to chain 2 and send traffic. - require.NoError(t, AddLaneWithDefaultPrices(e.Env, state, chain1, chain2)) + require.NoError(t, AddLaneWithDefaultPricesAndFeeQuoterConfig(e.Env, state, chain1, chain2, false)) ReplayLogs(t, e.Env.Offchain, replayBlocks) time.Sleep(30 * time.Second) @@ -87,7 +129,7 @@ func TestAddLane(t *testing.T) { require.Equal(t, uint64(1), msgSentEvent1.SequenceNumber) // Add another lane - require.NoError(t, AddLaneWithDefaultPrices(e.Env, state, chain2, chain1)) + require.NoError(t, AddLaneWithDefaultPricesAndFeeQuoterConfig(e.Env, state, chain2, chain1, false)) // Send traffic on the second lane and it should succeed latesthdr, err = e.Env.Chains[chain1].Client.HeaderByNumber(testcontext.Get(t), nil) diff --git a/deployment/ccip/changeset/deploy.go b/deployment/ccip/changeset/deploy.go index a3736075c48..a53dd7f3f2c 100644 --- a/deployment/ccip/changeset/deploy.go +++ b/deployment/ccip/changeset/deploy.go @@ -7,10 +7,9 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "golang.org/x/sync/errgroup" - "github.com/smartcontractkit/chainlink-ccip/pluginconfig" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/deployment" @@ -378,10 +377,15 @@ func configureChain( if !ok { return fmt.Errorf("chain state not found for chain %d", chain.Selector) } + ocrParams, ok := c.OCRParams[chain.Selector] + if !ok { + return fmt.Errorf("OCR params not found for chain %d", chain.Selector) + } if chainState.OffRamp == nil { return fmt.Errorf("off ramp not found for chain %d", chain.Selector) } - tokenInfo := c.TokenConfig.GetTokenInfo(e.Logger, existingState.Chains[chainSel].LinkToken, existingState.Chains[chainSel].Weth9) + // TODO : better handling - need to scale this for more tokens + ocrParams.CommitOffChainConfig.TokenInfo = c.TokenConfig.GetTokenInfo(e.Logger, existingState.Chains[chainSel].LinkToken, existingState.Chains[chainSel].Weth9) _, err = AddChainConfig( e.Logger, e.Chains[c.HomeChainSel], @@ -391,33 +395,22 @@ func configureChain( if err != nil { return err } - var tokenDataObserversConf []pluginconfig.TokenDataObserverConfig if enabled, ok := c.USDCConfig.EnabledChainMap()[chainSel]; ok && enabled { - tokenDataObserversConf = []pluginconfig.TokenDataObserverConfig{{ - Type: pluginconfig.USDCCCTPHandlerType, - Version: "1.0", - USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ - Tokens: c.USDCConfig.CCTPTokenConfig, - AttestationAPI: c.USDCConfig.API, - AttestationAPITimeout: c.USDCConfig.APITimeout, - AttestationAPIInterval: c.USDCConfig.APIInterval, - }, - }} + ocrParams.ExecuteOffChainConfig.TokenDataObservers = append(ocrParams.ExecuteOffChainConfig.TokenDataObservers, c.USDCConfig.ToTokenDataObserverConfig()...) } + ocrParams.CommitOffChainConfig.PriceFeedChainSelector = cciptypes.ChainSelector(c.FeedChainSel) // For each chain, we create a DON on the home chain (2 OCR instances) - if err := AddDON( + if err := addDON( e.Logger, c.OCRSecrets, capReg, ccipHome, rmnHome.Address(), chainState.OffRamp, - c.FeedChainSel, - tokenInfo, chain, e.Chains[c.HomeChainSel], nodes.NonBootstraps(), - tokenDataObserversConf, + ocrParams, ); err != nil { e.Logger.Errorw("Failed to add DON", "err", err) return err diff --git a/deployment/ccip/changeset/deploy_chain.go b/deployment/ccip/changeset/deploy_chain.go index 4c37603c64d..d0f44724070 100644 --- a/deployment/ccip/changeset/deploy_chain.go +++ b/deployment/ccip/changeset/deploy_chain.go @@ -16,6 +16,9 @@ var _ deployment.ChangeSet[DeployChainContractsConfig] = DeployChainContracts // changeset again with the same input to retry the failed deployment. // Caller should update the environment's address book with the returned addresses. func DeployChainContracts(env deployment.Environment, c DeployChainContractsConfig) (deployment.ChangesetOutput, error) { + if err := c.Validate(); err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("invalid DeployChainContractsConfig: %w", err) + } newAddresses := deployment.NewMemoryAddressBook() err := deployChainContractsForChains(env, newAddresses, c.HomeChainSelector, c.ChainSelectors) if err != nil { diff --git a/deployment/ccip/changeset/deploy_home_chain.go b/deployment/ccip/changeset/deploy_home_chain.go index 446328c0530..881f7c386c3 100644 --- a/deployment/ccip/changeset/deploy_home_chain.go +++ b/deployment/ccip/changeset/deploy_home_chain.go @@ -16,11 +16,10 @@ import ( "github.com/smartcontractkit/chainlink-ccip/chainconfig" "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" - "github.com/smartcontractkit/chainlink-ccip/pluginconfig" "github.com/smartcontractkit/chainlink-common/pkg/logger" - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" @@ -437,23 +436,20 @@ func ValidateCCIPHomeConfigSetUp( return nil } -func AddDON( +func addDON( lggr logger.Logger, ocrSecrets deployment.OCRSecrets, capReg *capabilities_registry.CapabilitiesRegistry, ccipHome *ccip_home.CCIPHome, rmnHomeAddress common.Address, offRamp *offramp.OffRamp, - feedChainSel uint64, - // Token address on Dest chain to aggregate address on feed chain - tokenInfo map[ccipocr3.UnknownEncodedAddress]pluginconfig.TokenInfo, dest deployment.Chain, home deployment.Chain, nodes deployment.Nodes, - tokenConfigs []pluginconfig.TokenDataObserverConfig, + ocrParams CCIPOCRParams, ) error { ocrConfigs, err := internal.BuildOCR3ConfigForCCIPHome( - ocrSecrets, offRamp, dest, feedChainSel, tokenInfo, nodes, rmnHomeAddress, tokenConfigs) + ocrSecrets, offRamp, dest, nodes, rmnHomeAddress, ocrParams.OCRParameters, ocrParams.CommitOffChainConfig, ocrParams.ExecuteOffChainConfig) if err != nil { return err } diff --git a/deployment/ccip/changeset/initial_add_chain.go b/deployment/ccip/changeset/initial_add_chain.go index 0e8da566626..338e3ea76e8 100644 --- a/deployment/ccip/changeset/initial_add_chain.go +++ b/deployment/ccip/changeset/initial_add_chain.go @@ -2,13 +2,20 @@ package changeset import ( "fmt" + "os" + "slices" + "sort" + "time" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" + "github.com/smartcontractkit/chainlink/deployment/common/types" ) var _ deployment.ChangeSet[NewChainsConfig] = ConfigureNewChains @@ -48,12 +55,44 @@ func (cfg USDCConfig) EnabledChainMap() map[uint64]bool { return m } +func (cfg USDCConfig) ToTokenDataObserverConfig() []pluginconfig.TokenDataObserverConfig { + return []pluginconfig.TokenDataObserverConfig{{ + Type: pluginconfig.USDCCCTPHandlerType, + Version: "1.0", + USDCCCTPObserverConfig: &pluginconfig.USDCCCTPObserverConfig{ + Tokens: cfg.CCTPTokenConfig, + AttestationAPI: cfg.API, + AttestationAPITimeout: cfg.APITimeout, + AttestationAPIInterval: cfg.APIInterval, + }, + }} +} + type USDCAttestationConfig struct { API string APITimeout *config.Duration APIInterval *config.Duration } +type CCIPOCRParams struct { + OCRParameters types.OCRParameters + CommitOffChainConfig pluginconfig.CommitOffchainConfig + ExecuteOffChainConfig pluginconfig.ExecuteOffchainConfig +} + +func (p CCIPOCRParams) Validate() error { + if err := p.OCRParameters.Validate(); err != nil { + return fmt.Errorf("invalid OCR parameters: %w", err) + } + if err := p.CommitOffChainConfig.Validate(); err != nil { + return fmt.Errorf("invalid commit off-chain config: %w", err) + } + if err := p.ExecuteOffChainConfig.Validate(); err != nil { + return fmt.Errorf("invalid execute off-chain config: %w", err) + } + return nil +} + type NewChainsConfig struct { HomeChainSel uint64 FeedChainSel uint64 @@ -62,6 +101,7 @@ type NewChainsConfig struct { USDCConfig USDCConfig // For setting OCR configuration OCRSecrets deployment.OCRSecrets + OCRParams map[uint64]CCIPOCRParams } func (c NewChainsConfig) Validate() error { @@ -106,5 +146,65 @@ func (c NewChainsConfig) Validate() error { return fmt.Errorf("invalid chain selector: %d - %w", chain, err) } } + // Validate OCR params + var ocrChains []uint64 + for chain, ocrParams := range c.OCRParams { + ocrChains = append(ocrChains, chain) + if _, exists := mapChainsToDeploy[chain]; !exists { + return fmt.Errorf("chain %d is not in chains to deploy", chain) + } + if err := ocrParams.Validate(); err != nil { + return fmt.Errorf("invalid OCR params for chain %d: %w", chain, err) + } + } + sort.Slice(ocrChains, func(i, j int) bool { return ocrChains[i] < ocrChains[j] }) + sort.Slice(c.ChainsToDeploy, func(i, j int) bool { return c.ChainsToDeploy[i] < c.ChainsToDeploy[j] }) + if !slices.Equal(ocrChains, c.ChainsToDeploy) { + return fmt.Errorf("mismatch in given OCR params and chains to deploy") + } return nil } + +func DefaultOCRParams( + feedChainSel uint64, + tokenInfo map[ccipocr3.UnknownEncodedAddress]pluginconfig.TokenInfo, + dataObserverConfig []pluginconfig.TokenDataObserverConfig, +) CCIPOCRParams { + return CCIPOCRParams{ + OCRParameters: types.OCRParameters{ + DeltaProgress: internal.DeltaProgress, + DeltaResend: internal.DeltaResend, + DeltaInitial: internal.DeltaInitial, + DeltaRound: internal.DeltaRound, + DeltaGrace: internal.DeltaGrace, + DeltaCertifiedCommitRequest: internal.DeltaCertifiedCommitRequest, + DeltaStage: internal.DeltaStage, + Rmax: internal.Rmax, + MaxDurationQuery: internal.MaxDurationQuery, + MaxDurationObservation: internal.MaxDurationObservation, + MaxDurationShouldAcceptAttestedReport: internal.MaxDurationShouldAcceptAttestedReport, + MaxDurationShouldTransmitAcceptedReport: internal.MaxDurationShouldTransmitAcceptedReport, + }, + ExecuteOffChainConfig: pluginconfig.ExecuteOffchainConfig{ + BatchGasLimit: internal.BatchGasLimit, + RelativeBoostPerWaitHour: internal.RelativeBoostPerWaitHour, + InflightCacheExpiry: *config.MustNewDuration(internal.InflightCacheExpiry), + RootSnoozeTime: *config.MustNewDuration(internal.RootSnoozeTime), + MessageVisibilityInterval: *config.MustNewDuration(internal.FirstBlockAge), + BatchingStrategyID: internal.BatchingStrategyID, + TokenDataObservers: dataObserverConfig, + }, + CommitOffChainConfig: pluginconfig.CommitOffchainConfig{ + RemoteGasPriceBatchWriteFrequency: *config.MustNewDuration(internal.RemoteGasPriceBatchWriteFrequency), + TokenPriceBatchWriteFrequency: *config.MustNewDuration(internal.TokenPriceBatchWriteFrequency), + TokenInfo: tokenInfo, + PriceFeedChainSelector: ccipocr3.ChainSelector(feedChainSel), + NewMsgScanBatchSize: merklemulti.MaxNumberTreeLeaves, + MaxReportTransmissionCheckAttempts: 5, + RMNEnabled: os.Getenv("ENABLE_RMN") == "true", // only enabled in manual test + RMNSignaturesTimeout: 30 * time.Minute, + MaxMerkleTreeSize: merklemulti.MaxNumberTreeLeaves, + SignObservationPrefix: "chainlink ccip 1.6 rmn observation", + }, + } +} diff --git a/deployment/ccip/changeset/internal/deploy_home_chain.go b/deployment/ccip/changeset/internal/deploy_home_chain.go index 7b4e6e9a27b..4fc0a9d1d60 100644 --- a/deployment/ccip/changeset/internal/deploy_home_chain.go +++ b/deployment/ccip/changeset/internal/deploy_home_chain.go @@ -3,7 +3,6 @@ package internal import ( "context" "fmt" - "os" "time" "github.com/ethereum/go-ethereum/accounts/abi" @@ -12,11 +11,10 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper" - "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" - "github.com/smartcontractkit/chainlink-common/pkg/config" - "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" + "github.com/smartcontractkit/chainlink/deployment" + types2 "github.com/smartcontractkit/chainlink/deployment/common/types" "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" @@ -30,7 +28,7 @@ const ( FirstBlockAge = 8 * time.Hour RemoteGasPriceBatchWriteFrequency = 30 * time.Minute - TokenPriceBatchWriteFrequency = 30 * time.Minute + TokenPriceBatchWriteFrequency = 3 * time.Second BatchGasLimit = 6_500_000 RelativeBoostPerWaitHour = 1.5 InflightCacheExpiry = 10 * time.Minute @@ -412,11 +410,11 @@ func BuildOCR3ConfigForCCIPHome( ocrSecrets deployment.OCRSecrets, offRamp *offramp.OffRamp, dest deployment.Chain, - feedChainSel uint64, - tokenInfo map[ccipocr3.UnknownEncodedAddress]pluginconfig.TokenInfo, nodes deployment.Nodes, rmnHomeAddress common.Address, - configs []pluginconfig.TokenDataObserverConfig, + ocrParams types2.OCRParameters, + commitOffchainCfg pluginconfig.CommitOffchainConfig, + execOffchainCfg pluginconfig.ExecuteOffchainConfig, ) (map[types.PluginType]ccip_home.CCIPHomeOCR3Config, error) { p2pIDs := nodes.PeerIDs() // Get OCR3 Config from helper @@ -445,25 +443,26 @@ func BuildOCR3ConfigForCCIPHome( var err2 error if pluginType == types.PluginTypeCCIPCommit { encodedOffchainConfig, err2 = pluginconfig.EncodeCommitOffchainConfig(pluginconfig.CommitOffchainConfig{ - RemoteGasPriceBatchWriteFrequency: *config.MustNewDuration(RemoteGasPriceBatchWriteFrequency), - TokenPriceBatchWriteFrequency: *config.MustNewDuration(TokenPriceBatchWriteFrequency), - PriceFeedChainSelector: ccipocr3.ChainSelector(feedChainSel), - TokenInfo: tokenInfo, - NewMsgScanBatchSize: merklemulti.MaxNumberTreeLeaves, - MaxReportTransmissionCheckAttempts: 5, - MaxMerkleTreeSize: merklemulti.MaxNumberTreeLeaves, - SignObservationPrefix: "chainlink ccip 1.6 rmn observation", - RMNEnabled: os.Getenv("ENABLE_RMN") == "true", // only enabled in manual test + RemoteGasPriceBatchWriteFrequency: commitOffchainCfg.RemoteGasPriceBatchWriteFrequency, + TokenPriceBatchWriteFrequency: commitOffchainCfg.TokenPriceBatchWriteFrequency, + PriceFeedChainSelector: commitOffchainCfg.PriceFeedChainSelector, + TokenInfo: commitOffchainCfg.TokenInfo, + NewMsgScanBatchSize: commitOffchainCfg.NewMsgScanBatchSize, + MaxReportTransmissionCheckAttempts: commitOffchainCfg.MaxReportTransmissionCheckAttempts, + MaxMerkleTreeSize: commitOffchainCfg.MaxMerkleTreeSize, + SignObservationPrefix: commitOffchainCfg.SignObservationPrefix, + RMNEnabled: commitOffchainCfg.RMNEnabled, + RMNSignaturesTimeout: commitOffchainCfg.RMNSignaturesTimeout, }) } else { encodedOffchainConfig, err2 = pluginconfig.EncodeExecuteOffchainConfig(pluginconfig.ExecuteOffchainConfig{ - BatchGasLimit: BatchGasLimit, - RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, - MessageVisibilityInterval: *config.MustNewDuration(FirstBlockAge), - InflightCacheExpiry: *config.MustNewDuration(InflightCacheExpiry), - RootSnoozeTime: *config.MustNewDuration(RootSnoozeTime), - BatchingStrategyID: BatchingStrategyID, - TokenDataObservers: configs, + BatchGasLimit: execOffchainCfg.BatchGasLimit, + RelativeBoostPerWaitHour: execOffchainCfg.RelativeBoostPerWaitHour, + MessageVisibilityInterval: execOffchainCfg.MessageVisibilityInterval, + InflightCacheExpiry: execOffchainCfg.InflightCacheExpiry, + RootSnoozeTime: execOffchainCfg.RootSnoozeTime, + BatchingStrategyID: execOffchainCfg.BatchingStrategyID, + TokenDataObservers: execOffchainCfg.TokenDataObservers, }) } if err2 != nil { @@ -472,22 +471,22 @@ func BuildOCR3ConfigForCCIPHome( signers, transmitters, configF, _, offchainConfigVersion, offchainConfig, err2 := ocr3confighelper.ContractSetConfigArgsDeterministic( ocrSecrets.EphemeralSk, ocrSecrets.SharedSecret, - DeltaProgress, - DeltaResend, - DeltaInitial, - DeltaRound, - DeltaGrace, - DeltaCertifiedCommitRequest, - DeltaStage, - Rmax, + ocrParams.DeltaProgress, + ocrParams.DeltaResend, + ocrParams.DeltaInitial, + ocrParams.DeltaRound, + ocrParams.DeltaGrace, + ocrParams.DeltaCertifiedCommitRequest, + ocrParams.DeltaStage, + ocrParams.Rmax, schedule, oracles, encodedOffchainConfig, nil, // maxDurationInitialization - MaxDurationQuery, - MaxDurationObservation, - MaxDurationShouldAcceptAttestedReport, - MaxDurationShouldTransmitAcceptedReport, + ocrParams.MaxDurationQuery, + ocrParams.MaxDurationObservation, + ocrParams.MaxDurationShouldAcceptAttestedReport, + ocrParams.MaxDurationShouldTransmitAcceptedReport, int(nodes.DefaultF()), []byte{}, // empty OnChainConfig ) diff --git a/deployment/ccip/changeset/test_helpers.go b/deployment/ccip/changeset/test_helpers.go index ac14a720035..5e8705d4757 100644 --- a/deployment/ccip/changeset/test_helpers.go +++ b/deployment/ccip/changeset/test_helpers.go @@ -17,6 +17,7 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" @@ -32,11 +33,12 @@ import ( "github.com/smartcontractkit/chainlink-ccip/pkg/reader" cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" - "github.com/smartcontractkit/chainlink-common/pkg/logger" - commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils" jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/environment/devenv" "github.com/smartcontractkit/chainlink/deployment/environment/memory" @@ -293,6 +295,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, state, err := LoadOnchainState(e.Env) require.NoError(t, err) tokenConfig := NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds) + ocrParams := make(map[uint64]CCIPOCRParams) usdcCCTPConfig := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) for _, chain := range usdcChains { @@ -303,7 +306,10 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, SourcePoolAddress: state.Chains[chain].USDCTokenPool.Address().String(), SourceMessageTransmitterAddr: state.Chains[chain].MockUSDCTransmitter.Address().String(), } + } + for _, chain := range allChains { timelocksPerChain[chain] = state.Chains[chain].Timelock + ocrParams[chain] = DefaultOCRParams(e.FeedChainSel, nil, nil) } var usdcCfg USDCAttestationConfig if len(usdcChains) > 0 { @@ -341,6 +347,7 @@ func NewMemoryEnvironmentWithJobsAndContracts(t *testing.T, lggr logger.Logger, USDCAttestationConfig: usdcCfg, CCTPTokenConfig: usdcCCTPConfig, }, + OCRParams: ocrParams, }, }, { @@ -498,7 +505,7 @@ func AddLanesForAll(e deployment.Environment, state CCIPOnChainState) error { for source := range e.Chains { for dest := range e.Chains { if source != dest { - err := AddLaneWithDefaultPrices(e, state, source, dest) + err := AddLaneWithDefaultPricesAndFeeQuoterConfig(e, state, source, dest, false) if err != nil { return err } @@ -809,11 +816,11 @@ func setTokenPoolCounterPart( ) error { tx, err := tokenPool.ApplyChainUpdates( chain.DeployerKey, + []uint64{}, []burn_mint_token_pool.TokenPoolChainUpdate{ { RemoteChainSelector: destChainSelector, - Allowed: true, - RemotePoolAddress: common.LeftPadBytes(destTokenPoolAddress.Bytes(), 32), + RemotePoolAddresses: [][]byte{common.LeftPadBytes(destTokenPoolAddress.Bytes(), 32)}, RemoteTokenAddress: common.LeftPadBytes(destTokenAddress.Bytes(), 32), OutboundRateLimiterConfig: burn_mint_token_pool.RateLimiterConfig{ IsEnabled: false, @@ -837,7 +844,7 @@ func setTokenPoolCounterPart( return err } - tx, err = tokenPool.SetRemotePool( + tx, err = tokenPool.AddRemotePool( chain.DeployerKey, destChainSelector, destTokenPoolAddress.Bytes(), @@ -918,6 +925,8 @@ func deployTransferTokenOneEnd( } } + tokenDecimals := uint8(18) + tokenContract, err := deployment.DeployContract(lggr, chain, addressBook, func(chain deployment.Chain) deployment.ContractDeploy[*burn_mint_erc677.BurnMintERC677] { USDCTokenAddr, tx, token, err2 := burn_mint_erc677.DeployBurnMintERC677( @@ -925,7 +934,7 @@ func deployTransferTokenOneEnd( chain.Client, tokenSymbol, tokenSymbol, - uint8(18), + tokenDecimals, big.NewInt(0).Mul(big.NewInt(1e9), big.NewInt(1e18)), ) return deployment.ContractDeploy[*burn_mint_erc677.BurnMintERC677]{ @@ -952,6 +961,7 @@ func deployTransferTokenOneEnd( chain.DeployerKey, chain.Client, tokenContract.Address, + tokenDecimals, []common.Address{}, common.HexToAddress(rmnAddress), common.HexToAddress(routerAddress), diff --git a/deployment/common/types/types.go b/deployment/common/types/types.go index 0efb226d73b..7fb602c3704 100644 --- a/deployment/common/types/types.go +++ b/deployment/common/types/types.go @@ -1,7 +1,9 @@ package types import ( + "fmt" "math/big" + "time" "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/ccip-owner-contracts/pkg/config" @@ -23,3 +25,58 @@ type MCMSWithTimelockConfig struct { TimelockExecutors []common.Address TimelockMinDelay *big.Int } + +type OCRParameters struct { + DeltaProgress time.Duration + DeltaResend time.Duration + DeltaInitial time.Duration + DeltaRound time.Duration + DeltaGrace time.Duration + DeltaCertifiedCommitRequest time.Duration + DeltaStage time.Duration + Rmax uint64 + MaxDurationQuery time.Duration + MaxDurationObservation time.Duration + MaxDurationShouldAcceptAttestedReport time.Duration + MaxDurationShouldTransmitAcceptedReport time.Duration +} + +func (params OCRParameters) Validate() error { + if params.DeltaProgress <= 0 { + return fmt.Errorf("deltaProgress must be positive") + } + if params.DeltaResend <= 0 { + return fmt.Errorf("deltaResend must be positive") + } + if params.DeltaInitial <= 0 { + return fmt.Errorf("deltaInitial must be positive") + } + if params.DeltaRound <= 0 { + return fmt.Errorf("deltaRound must be positive") + } + if params.DeltaGrace <= 0 { + return fmt.Errorf("deltaGrace must be positive") + } + if params.DeltaCertifiedCommitRequest <= 0 { + return fmt.Errorf("deltaCertifiedCommitRequest must be positive") + } + if params.DeltaStage <= 0 { + return fmt.Errorf("deltaStage must be positive") + } + if params.Rmax <= 0 { + return fmt.Errorf("rmax must be positive") + } + if params.MaxDurationQuery <= 0 { + return fmt.Errorf("maxDurationQuery must be positive") + } + if params.MaxDurationObservation <= 0 { + return fmt.Errorf("maxDurationObservation must be positive") + } + if params.MaxDurationShouldAcceptAttestedReport <= 0 { + return fmt.Errorf("maxDurationShouldAcceptAttestedReport must be positive") + } + if params.MaxDurationShouldTransmitAcceptedReport <= 0 { + return fmt.Errorf("maxDurationShouldTransmitAcceptedReport must be positive") + } + return nil +} diff --git a/deployment/common/view/v1_0/capreg.go b/deployment/common/view/v1_0/capreg.go index 2ddd5a13463..3274cc4e97f 100644 --- a/deployment/common/view/v1_0/capreg.go +++ b/deployment/common/view/v1_0/capreg.go @@ -26,7 +26,7 @@ type CapabilityRegistryView struct { // MarshalJSON marshals the CapabilityRegistryView to JSON. It includes the Capabilities, Nodes, Nops, and Dons // and a denormalized summary of the Dons with their associated Nodes and Capabilities, which is useful for a high-level view -func (v CapabilityRegistryView) MarshalJSON() ([]byte, error) { +func (v *CapabilityRegistryView) MarshalJSON() ([]byte, error) { // Alias to avoid recursive calls type Alias struct { types.ContractMetaData @@ -51,6 +51,36 @@ func (v CapabilityRegistryView) MarshalJSON() ([]byte, error) { return json.MarshalIndent(&a, "", " ") } +// UnmarshalJSON unmarshals the CapabilityRegistryView from JSON. Since the CapabilityRegistryView doesn't hold a DonCapabilities field, +// it is not unmarshaled. +func (v *CapabilityRegistryView) UnmarshalJSON(data []byte) error { + // Alias to avoid recursive calls + type Alias struct { + types.ContractMetaData + Capabilities []CapabilityView `json:"capabilities,omitempty"` + Nodes []NodeView `json:"nodes,omitempty"` + Nops []NopView `json:"nops,omitempty"` + Dons []DonView `json:"dons,omitempty"` + DonCapabilities []DonDenormalizedView `json:"don_capabilities_summary,omitempty"` + } + a := Alias{ + ContractMetaData: v.ContractMetaData, + Capabilities: v.Capabilities, + Nodes: v.Nodes, + Nops: v.Nops, + Dons: v.Dons, + } + if err := json.Unmarshal(data, &a); err != nil { + return err + } + v.ContractMetaData = a.ContractMetaData + v.Capabilities = a.Capabilities + v.Nodes = a.Nodes + v.Nops = a.Nops + v.Dons = a.Dons + return nil +} + // GenerateCapabilityRegistryView generates a CapRegView from a CapabilitiesRegistry contract. func GenerateCapabilityRegistryView(capReg *capabilities_registry.CapabilitiesRegistry) (CapabilityRegistryView, error) { tv, err := types.NewContractMetaData(capReg, capReg.Address()) @@ -112,7 +142,7 @@ type DonDenormalizedView struct { // Nodes and Capabilities. This is a useful form of the CapabilityRegistryView, but it is not definitive. // The full CapRegView should be used for the most accurate information as it can contain // Capabilities and Nodes the are not associated with any Don. -func (v CapabilityRegistryView) DonDenormalizedView() ([]DonDenormalizedView, error) { +func (v *CapabilityRegistryView) DonDenormalizedView() ([]DonDenormalizedView, error) { var out []DonDenormalizedView for _, don := range v.Dons { var nodes []NodeDenormalizedView @@ -140,6 +170,91 @@ func (v CapabilityRegistryView) DonDenormalizedView() ([]DonDenormalizedView, er return out, nil } +func (v *CapabilityRegistryView) NodesToNodesParams() ([]capabilities_registry.CapabilitiesRegistryNodeParams, error) { + var nodesParams []capabilities_registry.CapabilitiesRegistryNodeParams + for _, node := range v.Nodes { + signer, err := hexTo32Bytes(node.Signer) + if err != nil { + return nil, err + } + encryptionPubKey, err := hexTo32Bytes(node.EncryptionPublicKey) + if err != nil { + return nil, err + } + capIDs := make([][32]byte, len(node.CapabilityIDs)) + for i, id := range node.CapabilityIDs { + cid, err := hexTo32Bytes(id) + if err != nil { + return nil, err + } + capIDs[i] = cid + } + nodesParams = append(nodesParams, capabilities_registry.CapabilitiesRegistryNodeParams{ + Signer: signer, + P2pId: node.P2pId, + EncryptionPublicKey: encryptionPubKey, + NodeOperatorId: node.NodeOperatorID, + HashedCapabilityIds: capIDs, + }) + } + + return nodesParams, nil +} + +func (v *CapabilityRegistryView) CapabilitiesToCapabilitiesParams() []capabilities_registry.CapabilitiesRegistryCapability { + var capabilitiesParams []capabilities_registry.CapabilitiesRegistryCapability + for _, capability := range v.Capabilities { + capabilitiesParams = append(capabilitiesParams, capabilities_registry.CapabilitiesRegistryCapability{ + LabelledName: capability.LabelledName, + Version: capability.Version, + CapabilityType: capability.CapabilityType, + ResponseType: capability.ResponseType, + ConfigurationContract: capability.ConfigurationContract, + }) + } + return capabilitiesParams +} + +func (v *CapabilityRegistryView) NopsToNopsParams() []capabilities_registry.CapabilitiesRegistryNodeOperator { + var nopsParams []capabilities_registry.CapabilitiesRegistryNodeOperator + for _, nop := range v.Nops { + nopsParams = append(nopsParams, capabilities_registry.CapabilitiesRegistryNodeOperator{ + Admin: nop.Admin, + Name: nop.Name, + }) + } + return nopsParams +} + +func (v *CapabilityRegistryView) CapabilityConfigToCapabilityConfigParams(don DonView) ([]capabilities_registry.CapabilitiesRegistryCapabilityConfiguration, error) { + var cfgs []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration + for _, cfg := range don.CapabilityConfigurations { + cid, err := hexTo32Bytes(cfg.ID) + if err != nil { + return nil, err + } + config, err := hex.DecodeString(cfg.Config) + if err != nil { + return nil, err + } + cfgs = append(cfgs, capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ + CapabilityId: cid, + Config: config, + }) + } + return cfgs, nil +} + +func hexTo32Bytes(val string) ([32]byte, error) { + var out [32]byte + b, err := hex.DecodeString(val) + if err != nil { + return out, err + } + copy(out[:], b) + return out, nil +} + // CapabilityView is a serialization-friendly view of a capability in the capabilities registry. type CapabilityView struct { ID string `json:"id"` // hex 32 bytes @@ -272,7 +387,7 @@ func NewNodeView(n capabilities_registry.INodeInfoProviderNodeInfo) NodeView { ConfigCount: n.ConfigCount, WorkflowDONID: n.WorkflowDONId, Signer: hex.EncodeToString(n.Signer[:]), - P2pId: p2pkey.PeerID(n.P2pId), + P2pId: n.P2pId, EncryptionPublicKey: hex.EncodeToString(n.EncryptionPublicKey[:]), }, NodeOperatorID: n.NodeOperatorId, @@ -328,7 +443,7 @@ func NewNopView(nop capabilities_registry.CapabilitiesRegistryNodeOperator) NopV } } -func (v CapabilityRegistryView) nodeDenormalizedView(n NodeView) (NodeDenormalizedView, error) { +func (v *CapabilityRegistryView) nodeDenormalizedView(n NodeView) (NodeDenormalizedView, error) { nop, err := nodeNop(n, v.Nops) if err != nil { return NodeDenormalizedView{}, err diff --git a/deployment/common/view/v1_0/capreg_test.go b/deployment/common/view/v1_0/capreg_test.go index 8ba7b880364..2f58034a619 100644 --- a/deployment/common/view/v1_0/capreg_test.go +++ b/deployment/common/view/v1_0/capreg_test.go @@ -4,9 +4,10 @@ import ( "math/big" "testing" + "github.com/stretchr/testify/assert" + "github.com/smartcontractkit/chainlink/deployment/common/view/types" cr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/stretchr/testify/assert" ) func TestCapRegView_Denormalize(t *testing.T) { diff --git a/deployment/environment.go b/deployment/environment.go index b9f3700bdc4..c55f4d3efe6 100644 --- a/deployment/environment.go +++ b/deployment/environment.go @@ -7,6 +7,7 @@ import ( "fmt" "math/big" "sort" + "strings" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -21,6 +22,7 @@ import ( csav1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/csa" jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" + "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/shared/ptypes" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" ) @@ -222,11 +224,14 @@ func (n Nodes) BootstrapLocators() []string { type Node struct { NodeID string + Name string + CSAKey string SelToOCRConfig map[chain_selectors.ChainDetails]OCRConfig PeerID p2pkey.PeerID IsBootstrap bool MultiAddr string AdminAddr string + Labels []*ptypes.Label } func (n Node) OCRConfigForChainDetails(details chain_selectors.ChainDetails) (OCRConfig, bool) { @@ -269,17 +274,50 @@ func MustPeerIDFromString(s string) p2pkey.PeerID { } type NodeChainConfigsLister interface { + ListNodes(ctx context.Context, in *nodev1.ListNodesRequest, opts ...grpc.CallOption) (*nodev1.ListNodesResponse, error) ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNodeChainConfigsRequest, opts ...grpc.CallOption) (*nodev1.ListNodeChainConfigsResponse, error) } // Gathers all the node info through JD required to be able to set -// OCR config for example. +// OCR config for example. nodeIDs can be JD IDs or PeerIDs func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) { + if len(nodeIDs) == 0 { + return nil, nil + } + // if nodeIDs starts with `p2p_` lookup by p2p_id instead + filterByPeerIDs := strings.HasPrefix(nodeIDs[0], "p2p_") + var filter *nodev1.ListNodesRequest_Filter + if filterByPeerIDs { + selector := strings.Join(nodeIDs, ",") + filter = &nodev1.ListNodesRequest_Filter{ + Enabled: 1, + Selectors: []*ptypes.Selector{ + { + Key: "p2p_id", + Op: ptypes.SelectorOp_IN, + Value: &selector, + }, + }, + } + } else { + filter = &nodev1.ListNodesRequest_Filter{ + Enabled: 1, + Ids: nodeIDs, + } + + } + nodesFromJD, err := oc.ListNodes(context.Background(), &nodev1.ListNodesRequest{ + Filter: filter, + }) + if err != nil { + return nil, fmt.Errorf("failed to list nodes: %w", err) + } + var nodes []Node - for _, nodeID := range nodeIDs { + for _, node := range nodesFromJD.GetNodes() { // TODO: Filter should accept multiple nodes nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ - NodeIds: []string{nodeID}, + NodeIds: []string{node.Id}, }}) if err != nil { return nil, err @@ -294,7 +332,6 @@ func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) { // Might make sense to change proto as peerID/multiAddr is 1-1 with nodeID? peerID = MustPeerIDFromString(chainConfig.Ocr2Config.P2PKeyBundle.PeerId) multiAddr = chainConfig.Ocr2Config.Multiaddr - adminAddr = chainConfig.AdminAddress if chainConfig.Ocr2Config.IsBootstrap { // NOTE: Assume same peerID for all chains. // Might make sense to change proto as peerID is 1-1 with nodeID? @@ -309,40 +346,59 @@ func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) { var cpk types3.ConfigEncryptionPublicKey copy(cpk[:], b) + var pubkey types3.OnchainPublicKey + if chainConfig.Chain.Type == nodev1.ChainType_CHAIN_TYPE_EVM { + // convert from pubkey to address + pubkey = common.HexToAddress(chainConfig.Ocr2Config.OcrKeyBundle.OnchainSigningAddress).Bytes() + } else { + pubkey = common.Hex2Bytes(chainConfig.Ocr2Config.OcrKeyBundle.OnchainSigningAddress) + } + ocrConfig := OCRConfig{ OffchainPublicKey: opk, - OnchainPublicKey: common.HexToAddress(chainConfig.Ocr2Config.OcrKeyBundle.OnchainSigningAddress).Bytes(), + OnchainPublicKey: pubkey, PeerID: MustPeerIDFromString(chainConfig.Ocr2Config.P2PKeyBundle.PeerId), TransmitAccount: types2.Account(chainConfig.AccountAddress), ConfigEncryptionPublicKey: cpk, KeyBundleID: chainConfig.Ocr2Config.OcrKeyBundle.BundleId, } - var details chain_selectors.ChainDetails + if chainConfig.Chain.Type == nodev1.ChainType_CHAIN_TYPE_EVM { + // NOTE: Assume same adminAddr for all chains. We always use EVM addr + adminAddr = chainConfig.AdminAddress + } + + var family string switch chainConfig.Chain.Type { - case nodev1.ChainType_CHAIN_TYPE_APTOS: - details, err = chain_selectors.GetChainDetailsByChainIDAndFamily(chainConfig.Chain.Id, chain_selectors.FamilyAptos) - if err != nil { - return nil, err - } case nodev1.ChainType_CHAIN_TYPE_EVM: - details, err = chain_selectors.GetChainDetailsByChainIDAndFamily(chainConfig.Chain.Id, chain_selectors.FamilyEVM) - if err != nil { - return nil, err - } + family = chain_selectors.FamilyEVM + case nodev1.ChainType_CHAIN_TYPE_APTOS: + family = chain_selectors.FamilyAptos + case nodev1.ChainType_CHAIN_TYPE_SOLANA: + family = chain_selectors.FamilySolana + case nodev1.ChainType_CHAIN_TYPE_STARKNET: + family = chain_selectors.FamilyStarknet default: return nil, fmt.Errorf("unsupported chain type %s", chainConfig.Chain.Type) } + details, err := chain_selectors.GetChainDetailsByChainIDAndFamily(chainConfig.Chain.Id, family) + if err != nil { + return nil, err + } + selToOCRConfig[details] = ocrConfig } nodes = append(nodes, Node{ - NodeID: nodeID, + NodeID: node.Id, + Name: node.Name, + CSAKey: node.PublicKey, SelToOCRConfig: selToOCRConfig, IsBootstrap: bootstrap, PeerID: peerID, MultiAddr: multiAddr, AdminAddr: adminAddr, + Labels: node.Labels, }) } diff --git a/deployment/environment/devenv/rmn_config.go b/deployment/environment/devenv/rmn_config.go index 59d5e5d1cdb..623499a6fe8 100644 --- a/deployment/environment/devenv/rmn_config.go +++ b/deployment/environment/devenv/rmn_config.go @@ -33,7 +33,7 @@ type SharedConfigNetworking struct { type HomeChain struct { Name string `toml:"name"` CapabilitiesRegistry string `toml:"capabilities_registry"` - CCIPConfig string `toml:"ccip_config"` + CCIPHome string `toml:"ccip_home"` RMNHome string `toml:"rmn_home"` } diff --git a/deployment/environment/memory/job_client.go b/deployment/environment/memory/job_client.go index 3d98b1f3f8d..98fb90ceffa 100644 --- a/deployment/environment/memory/job_client.go +++ b/deployment/environment/memory/job_client.go @@ -190,16 +190,17 @@ func (j JobClient) ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNode if err != nil { return nil, err } - chainID, err := chainsel.ChainIdFromSelector(selector) - if err != nil { - return nil, err - } - if family == chainsel.FamilyEVM { // already handled above continue } + // NOTE: this supports non-EVM too + chainID, err := chainsel.GetChainIDFromSelector(selector) + if err != nil { + return nil, err + } + var ocrtype chaintype.ChainType switch family { case chainsel.FamilyEVM: @@ -213,7 +214,7 @@ func (j JobClient) ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNode case chainsel.FamilyAptos: ocrtype = chaintype.Aptos default: - panic(fmt.Sprintf("Unsupported chain family %v", family)) + return nil, fmt.Errorf("Unsupported chain family %v", family) } bundle := n.Keys.OCRKeyBundles[ocrtype] @@ -244,7 +245,7 @@ func (j JobClient) ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNode chainConfigs = append(chainConfigs, &nodev1.ChainConfig{ Chain: &nodev1.Chain{ - Id: strconv.Itoa(int(chainID)), + Id: chainID, Type: ctype, }, AccountAddress: "", // TODO: support AccountAddress diff --git a/deployment/environment/memory/node.go b/deployment/environment/memory/node.go index c2e4e457fbd..fd08d3cf17b 100644 --- a/deployment/environment/memory/node.go +++ b/deployment/environment/memory/node.go @@ -78,6 +78,10 @@ func NewNode( ) *Node { evmchains := make(map[uint64]EVMChain) for _, chain := range chains { + // we're only mapping evm chains here + if family, err := chainsel.GetSelectorFamily(chain.Selector); err != nil || family != chainsel.FamilyEVM { + continue + } evmChainID, err := chainsel.ChainIdFromSelector(chain.Selector) if err != nil { t.Fatal(err) diff --git a/deployment/go.mod b/deployment/go.mod index 8c739ea9eb9..084e3b4f533 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -21,9 +21,9 @@ require ( github.com/rs/zerolog v1.33.0 github.com/sethvargo/go-retry v0.2.4 github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 - github.com/smartcontractkit/chain-selectors v1.0.30 + github.com/smartcontractkit/chain-selectors v1.0.31 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.13 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/deployment/go.sum b/deployment/go.sum index c28d30aeaf2..41beed6c8f5 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1378,14 +1378,14 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 h1:qQH6fZZe31nBAG6INHph3z5ysDTPptyu0TR9uoJ1+ok= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86/go.mod h1:WtWOoVQQEHxRHL2hNmuRrvDfYfQG/CioFNoa9Rr2mBE= -github.com/smartcontractkit/chain-selectors v1.0.30 h1:jk+xVRocgQ/uvKLSd1JzeHJ/v+EKu1BjrreaSGqKzjo= -github.com/smartcontractkit/chain-selectors v1.0.30/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= +github.com/smartcontractkit/chain-selectors v1.0.31 h1:oRHyK88KnsCh4OdU2hr0u70pm3KUgyMDyK0v0aOtUk4= +github.com/smartcontractkit/chain-selectors v1.0.31/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec h1:5vS1k8Qn09p8SQ3JzvS8iy4Pve7s3aVq+UPIdl74smY= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec/go.mod h1:4adKaHNaxFsRvV/lYfqtbsWyyvIPUMLR0FdOJN/ljis= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b h1:mm46AlaafEhvGjJvuAb0VoLLM3NKAVnwKZ+iUCNL/sg= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b/go.mod h1:ny87uTW6hLjCTLiBqBRNFEhETSXhHWevYlPclT5lSco= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d h1:0tnjo1gpG16PHAouXamgDAAu6e7PWaM0Ppq6dMWnjx0= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d/go.mod h1:ny87uTW6hLjCTLiBqBRNFEhETSXhHWevYlPclT5lSco= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f h1:BwrIaQIx5Iy6eT+DfLhFfK2XqjxRm74mVdlX8gbu4dw= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f/go.mod h1:wHtwSR3F1CQSJJZDQKuqaqFYnvkT+kMyget7dl8Clvo= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241114154055-8d29ea018b57 h1:1BMTG66HnCIz+KMBWGvyzELNM6VHGwv2WKFhN7H49Sg= diff --git a/deployment/keystone/capability_registry_deployer.go b/deployment/keystone/capability_registry_deployer.go index efe1d23f11f..a4648c27905 100644 --- a/deployment/keystone/capability_registry_deployer.go +++ b/deployment/keystone/capability_registry_deployer.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) diff --git a/deployment/keystone/changeset/deploy_registry.go b/deployment/keystone/changeset/deploy_registry.go index 2c08e5ca8b7..e9b142812d7 100644 --- a/deployment/keystone/changeset/deploy_registry.go +++ b/deployment/keystone/changeset/deploy_registry.go @@ -7,11 +7,9 @@ import ( kslib "github.com/smartcontractkit/chainlink/deployment/keystone" ) -func DeployCapabilityRegistry(env deployment.Environment, config interface{}) (deployment.ChangesetOutput, error) { - registrySelector, ok := config.(uint64) - if !ok { - return deployment.ChangesetOutput{}, deployment.ErrInvalidConfig - } +var _ deployment.ChangeSet[uint64] = DeployCapabilityRegistry + +func DeployCapabilityRegistry(env deployment.Environment, registrySelector uint64) (deployment.ChangesetOutput, error) { chain, ok := env.Chains[registrySelector] if !ok { return deployment.ChangesetOutput{}, fmt.Errorf("chain not found in environment") diff --git a/deployment/keystone/changeset/deploy_registry_test.go b/deployment/keystone/changeset/deploy_registry_test.go index 6aa383ef68c..9abf357f2a8 100644 --- a/deployment/keystone/changeset/deploy_registry_test.go +++ b/deployment/keystone/changeset/deploy_registry_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" ) diff --git a/deployment/keystone/changeset/internal/update_don_test.go b/deployment/keystone/changeset/internal/update_don_test.go index 12ccfe290b1..e500ade60d7 100644 --- a/deployment/keystone/changeset/internal/update_don_test.go +++ b/deployment/keystone/changeset/internal/update_don_test.go @@ -2,14 +2,16 @@ package internal_test import ( "bytes" + "encoding/hex" + "fmt" "math/big" "sort" + "strconv" "testing" "github.com/ethereum/go-ethereum/common" chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-common/pkg/logger" - nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/keystone" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" @@ -22,9 +24,12 @@ import ( "github.com/stretchr/testify/require" ) +var ( + registryChain = chainsel.TEST_90000001 +) + func TestUpdateDon(t *testing.T) { var ( - registryChain = chainsel.TEST_90000001 // nodes p2p_1 = p2pkey.MustNewV2XXXTestingOnly(big.NewInt(100)) pubKey_1 = "11114981a6119ca3f932cdb8c402d71a72d672adae7849f581ecff8b8e1098e7" // valid csa key @@ -98,14 +103,14 @@ func TestUpdateDon(t *testing.T) { dons: []kslib.DonInfo{ { Name: "don 1", - Nodes: []keystone.Node{node_1, node_2, node_3, node_4}, + Nodes: []deployment.Node{node_1, node_2, node_3, node_4}, Capabilities: []kcr.CapabilitiesRegistryCapability{cap_A}, }, }, nops: []keystone.NOP{ { Name: "nop 1", - Nodes: []string{node_1.ID, node_2.ID, node_3.ID, node_4.ID}, + Nodes: []string{node_1.NodeID, node_2.NodeID, node_3.NodeID, node_4.NodeID}, }, }, } @@ -170,27 +175,36 @@ type minimalNodeCfg struct { admin common.Address } -func newNode(t *testing.T, cfg minimalNodeCfg) keystone.Node { +func newNode(t *testing.T, cfg minimalNodeCfg) deployment.Node { t.Helper() - return keystone.Node{ - ID: cfg.id, - PublicKey: &cfg.pubKey, - ChainConfigs: []*nodev1.ChainConfig{ - { - Chain: &nodev1.Chain{ - Id: "test chain", - Type: nodev1.ChainType_CHAIN_TYPE_EVM, - }, - AdminAddress: cfg.admin.String(), - Ocr2Config: &nodev1.OCR2Config{ - P2PKeyBundle: &nodev1.OCR2Config_P2PKeyBundle{ - PeerId: cfg.p2p.PeerID().String(), - }, - OcrKeyBundle: &nodev1.OCR2Config_OCRKeyBundle{ - OnchainSigningAddress: cfg.signingAddr, - }, - }, + registryChainID, err := chainsel.ChainIdFromSelector(registryChain.Selector) + if err != nil { + panic(err) + } + registryChainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(strconv.Itoa(int(registryChainID)), chainsel.FamilyEVM) + if err != nil { + panic(err) + } + + signingAddr, err := hex.DecodeString(cfg.signingAddr) + require.NoError(t, err) + + var pubkey [32]byte + if _, err := hex.Decode(pubkey[:], []byte(cfg.pubKey)); err != nil { + panic(fmt.Sprintf("failed to decode pubkey %s: %v", pubkey, err)) + } + + return deployment.Node{ + NodeID: cfg.id, + PeerID: cfg.p2p.PeerID(), + CSAKey: cfg.pubKey, + AdminAddr: cfg.admin.String(), + SelToOCRConfig: map[chainsel.ChainDetails]deployment.OCRConfig{ + registryChainDetails: { + OnchainPublicKey: signingAddr, + PeerID: cfg.p2p.PeerID(), + ConfigEncryptionPublicKey: pubkey, }, }, } @@ -214,10 +228,10 @@ func setupUpdateDonTest(t *testing.T, lggr logger.Logger, cfg setupUpdateDonTest func newSetupTestRegistryRequest(t *testing.T, dons []kslib.DonInfo, nops []keystone.NOP) *kstest.SetupTestRegistryRequest { t.Helper() - nodes := make(map[string]keystone.Node) + nodes := make(map[string]deployment.Node) for _, don := range dons { for _, node := range don.Nodes { - nodes[node.ID] = node + nodes[node.NodeID] = node } } nopsToNodes := makeNopToNodes(t, nops, nodes) @@ -231,7 +245,7 @@ func newSetupTestRegistryRequest(t *testing.T, dons []kslib.DonInfo, nops []keys return req } -func makeNopToNodes(t *testing.T, nops []keystone.NOP, nodes map[string]keystone.Node) map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc { +func makeNopToNodes(t *testing.T, nops []keystone.NOP, nodes map[string]deployment.Node) map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc { nopToNodes := make(map[kcr.CapabilitiesRegistryNodeOperator][]*internal.P2PSignerEnc) for _, nop := range nops { @@ -239,15 +253,15 @@ func makeNopToNodes(t *testing.T, nops []keystone.NOP, nodes map[string]keystone // so we can just use the first one crnop := kcr.CapabilitiesRegistryNodeOperator{ Name: nop.Name, - Admin: common.HexToAddress(nodes[nop.Nodes[0]].ChainConfigs[0].AdminAddress), + Admin: common.HexToAddress(nodes[nop.Nodes[0]].AdminAddr), } var signers []*internal.P2PSignerEnc for _, nodeID := range nop.Nodes { node := nodes[nodeID] - require.NotNil(t, node.PublicKey, "public key is nil %s", node.ID) + require.NotNil(t, node.CSAKey, "public key is nil %s", node.NodeID) // all chain configs are the same wrt admin address & node keys - p, err := kscs.NewP2PSignerEncFromJD(node.ChainConfigs[0], *node.PublicKey) - require.NoError(t, err, "failed to make p2p signer enc from clo nod %s", node.ID) + p, err := kscs.NewP2PSignerEnc(&node, registryChain.Selector) + require.NoError(t, err, "failed to make p2p signer enc from clo nod %s", node.NodeID) signers = append(signers, p) } nopToNodes[crnop] = signers @@ -260,8 +274,8 @@ func makeP2PToCapabilities(t *testing.T, dons []kslib.DonInfo) map[p2pkey.PeerID for _, don := range dons { for _, node := range don.Nodes { for _, cap := range don.Capabilities { - p, err := kscs.NewP2PSignerEncFromJD(node.ChainConfigs[0], *node.PublicKey) - require.NoError(t, err, "failed to make p2p signer enc from clo nod %s", node.ID) + p, err := kscs.NewP2PSignerEnc(&node, registryChain.Selector) + require.NoError(t, err, "failed to make p2p signer enc from clo nod %s", node.NodeID) p2pToCapabilities[p.P2PKey] = append(p2pToCapabilities[p.P2PKey], cap) } } @@ -282,8 +296,8 @@ func testDon(t *testing.T, don kslib.DonInfo) kstest.Don { for _, node := range don.Nodes { // all chain configs are the same wrt admin address & node keys // so we can just use the first one - p, err := kscs.NewP2PSignerEncFromJD(node.ChainConfigs[0], *node.PublicKey) - require.NoError(t, err, "failed to make p2p signer enc from clo nod %s", node.ID) + p, err := kscs.NewP2PSignerEnc(&node, registryChain.Selector) + require.NoError(t, err, "failed to make p2p signer enc from clo nod %s", node.NodeID) p2pids = append(p2pids, p.P2PKey) } @@ -299,11 +313,3 @@ func testDon(t *testing.T, don kslib.DonInfo) kstest.Don { CapabilityConfigs: capabilityConfigs, } } - -func newP2PSignerEnc(signer [32]byte, p2pkey p2pkey.PeerID, encryptionPublicKey [32]byte) *internal.P2PSignerEnc { - return &internal.P2PSignerEnc{ - Signer: signer, - P2PKey: p2pkey, - EncryptionPublicKey: encryptionPublicKey, - } -} diff --git a/deployment/keystone/changeset/types.go b/deployment/keystone/changeset/types.go deleted file mode 100644 index fb609041792..00000000000 --- a/deployment/keystone/changeset/types.go +++ /dev/null @@ -1,43 +0,0 @@ -package changeset - -import ( - "encoding/hex" - "errors" - "fmt" - - v1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" -) - -func NewP2PSignerEncFromJD(ccfg *v1.ChainConfig, pubkeyStr string) (*P2PSignerEnc, error) { - if ccfg == nil { - return nil, errors.New("nil ocr2config") - } - var pubkey [32]byte - if _, err := hex.Decode(pubkey[:], []byte(pubkeyStr)); err != nil { - return nil, fmt.Errorf("failed to decode pubkey %s: %w", pubkey, err) - } - ocfg := ccfg.Ocr2Config - p2p := p2pkey.PeerID{} - if err := p2p.UnmarshalString(ocfg.P2PKeyBundle.PeerId); err != nil { - return nil, fmt.Errorf("failed to unmarshal peer id %s: %w", ocfg.P2PKeyBundle.PeerId, err) - } - - signer := ocfg.OcrKeyBundle.OnchainSigningAddress - if len(signer) != 40 { - return nil, fmt.Errorf("invalid onchain signing address %s", ocfg.OcrKeyBundle.OnchainSigningAddress) - } - signerB, err := hex.DecodeString(signer) - if err != nil { - return nil, fmt.Errorf("failed to convert signer %s: %w", signer, err) - } - - var sigb [32]byte - copy(sigb[:], signerB) - - return &P2PSignerEnc{ - Signer: sigb, - P2PKey: p2p, - EncryptionPublicKey: pubkey, // TODO. no current way to get this from the node itself (and therefore not in clo or jd) - }, nil -} diff --git a/deployment/keystone/changeset/update_node_capabilities.go b/deployment/keystone/changeset/update_node_capabilities.go index 0b6c4fb5462..1d6dde6af5a 100644 --- a/deployment/keystone/changeset/update_node_capabilities.go +++ b/deployment/keystone/changeset/update_node_capabilities.go @@ -3,11 +3,11 @@ package changeset import ( "encoding/json" "fmt" + "strconv" chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink/deployment" - "github.com/smartcontractkit/chainlink/deployment/keystone" kslib "github.com/smartcontractkit/chainlink/deployment/keystone" "github.com/smartcontractkit/chainlink/deployment/keystone/changeset/internal" @@ -19,15 +19,29 @@ var _ deployment.ChangeSet[*MutateNodeCapabilitiesRequest] = UpdateNodeCapabilit type P2PSignerEnc = internal.P2PSignerEnc -func NewP2PSignerEnc(n *keystone.Node, registryChainSel uint64) (*P2PSignerEnc, error) { - p2p, signer, enc, err := kslib.ExtractKeys(n, registryChainSel) +func NewP2PSignerEnc(n *deployment.Node, registryChainSel uint64) (*P2PSignerEnc, error) { + // TODO: deduplicate everywhere + registryChainID, err := chainsel.ChainIdFromSelector(registryChainSel) if err != nil { - return nil, fmt.Errorf("failed to extract keys: %w", err) + return nil, err } + registryChainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(strconv.Itoa(int(registryChainID)), chainsel.FamilyEVM) + if err != nil { + return nil, err + } + evmCC, exists := n.SelToOCRConfig[registryChainDetails] + if !exists { + return nil, fmt.Errorf("NewP2PSignerEnc: registryChainSel not found on node: %v", registryChainSel) + } + var signer [32]byte + copy(signer[:], evmCC.OnchainPublicKey) + var csakey [32]byte + copy(csakey[:], evmCC.ConfigEncryptionPublicKey[:]) + return &P2PSignerEnc{ Signer: signer, - P2PKey: p2p, - EncryptionPublicKey: enc, + P2PKey: n.PeerID, + EncryptionPublicKey: csakey, }, nil } diff --git a/deployment/keystone/changeset/view_test.go b/deployment/keystone/changeset/view_test.go index 2d4569dfbec..023b4462549 100644 --- a/deployment/keystone/changeset/view_test.go +++ b/deployment/keystone/changeset/view_test.go @@ -7,6 +7,7 @@ import ( "go.uber.org/zap/zapcore" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" ) diff --git a/deployment/keystone/contract_set.go b/deployment/keystone/contract_set.go index a0446dcfce0..ccd89f6905f 100644 --- a/deployment/keystone/contract_set.go +++ b/deployment/keystone/contract_set.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment" ) diff --git a/deployment/keystone/deploy.go b/deployment/keystone/deploy.go index 3019f934a96..874b98600ae 100644 --- a/deployment/keystone/deploy.go +++ b/deployment/keystone/deploy.go @@ -7,8 +7,8 @@ import ( "encoding/hex" "errors" "fmt" - "slices" "sort" + "strconv" "strings" "time" @@ -16,8 +16,6 @@ import ( "github.com/ethereum/go-ethereum/rpc" "golang.org/x/exp/maps" - nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" - "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/shared/ptypes" "github.com/smartcontractkit/chainlink/deployment" "google.golang.org/protobuf/proto" @@ -30,7 +28,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" kf "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/forwarder" - kocr3 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/ocr3_capability" "github.com/smartcontractkit/chainlink-common/pkg/logger" ) @@ -150,78 +147,10 @@ func DeployContracts(lggr logger.Logger, e *deployment.Environment, chainSel uin // DonInfo is DonCapabilities, but expanded to contain node information type DonInfo struct { Name string - Nodes []Node + Nodes []deployment.Node Capabilities []kcr.CapabilitiesRegistryCapability // every capability is hosted on each node } -// TODO: merge with deployment/environment.go Node -type Node struct { - ID string - P2PID string - Name string - PublicKey *string - ChainConfigs []*nodev1.ChainConfig -} - -// TODO: merge with deployment/environment.go NodeInfo, we currently lookup based on p2p_id, and chain-selectors needs non-EVM support -func NodesFromJD(name string, nodeIDs []string, jd deployment.OffchainClient) ([]Node, error) { - // lookup nodes based on p2p_ids - var nodes []Node - selector := strings.Join(nodeIDs, ",") - nodesFromJD, err := jd.ListNodes(context.Background(), &nodev1.ListNodesRequest{ - Filter: &nodev1.ListNodesRequest_Filter{ - Enabled: 1, - Selectors: []*ptypes.Selector{ - { - Key: "p2p_id", - Op: ptypes.SelectorOp_IN, - Value: &selector, - }, - }, - }, - }) - if err != nil { - return nil, fmt.Errorf("failed to list nodes '%s': %w", name, err) - } - - for _, id := range nodeIDs { - idx := slices.IndexFunc(nodesFromJD.GetNodes(), func(node *nodev1.Node) bool { - return slices.ContainsFunc(node.Labels, func(label *ptypes.Label) bool { - return label.Key == "p2p_id" && *label.Value == id - }) - }) - if idx < 0 { - var got []string - for _, node := range nodesFromJD.GetNodes() { - for _, label := range node.Labels { - if label.Key == "p2p_id" { - got = append(got, *label.Value) - } - } - } - return nil, fmt.Errorf("node id %s not found in list '%s'", id, strings.Join(got, ",")) - } - - jdNode := nodesFromJD.Nodes[idx] - // TODO: Filter should accept multiple nodes - nodeChainConfigs, err := jd.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ - NodeIds: []string{jdNode.Id}, // must use the jd-specific internal node id - }}) - if err != nil { - return nil, err - } - - nodes = append(nodes, Node{ - ID: jdNode.Id, - P2PID: id, - Name: name, - PublicKey: &jdNode.PublicKey, - ChainConfigs: nodeChainConfigs.GetChainConfigs(), - }) - } - return nodes, nil -} - func DonInfos(dons []DonCapabilities, jd deployment.OffchainClient) ([]DonInfo, error) { var donInfos []DonInfo for _, don := range dons { @@ -229,7 +158,7 @@ func DonInfos(dons []DonCapabilities, jd deployment.OffchainClient) ([]DonInfo, for _, nop := range don.Nops { nodeIDs = append(nodeIDs, nop.Nodes...) } - nodes, err := NodesFromJD(don.Name, nodeIDs, jd) + nodes, err := deployment.NodeInfo(nodeIDs, jd) if err != nil { return nil, err } @@ -277,7 +206,7 @@ func ConfigureRegistry(ctx context.Context, lggr logger.Logger, req ConfigureCon // all the subsequent calls to the registry are in terms of nodes // compute the mapping of dons to their nodes for reuse in various registry calls - donToOcr2Nodes, err := mapDonsToNodes(donInfos, true, req.RegistryChainSel) + donToNodes, err := mapDonsToNodes(donInfos, true, req.RegistryChainSel) if err != nil { return nil, fmt.Errorf("failed to map dons to nodes: %w", err) } @@ -318,7 +247,7 @@ func ConfigureRegistry(ctx context.Context, lggr logger.Logger, req ConfigureCon registry: registry, chain: registryChain, nopToNodeIDs: nopsToNodeIDs, - donToOcr2Nodes: donToOcr2Nodes, + donToNodes: donToNodes, donToCapabilities: capabilitiesResp.donToCapabilities, nops: nopsResp.Nops, }) @@ -335,7 +264,7 @@ func ConfigureRegistry(ctx context.Context, lggr logger.Logger, req ConfigureCon chain: registryChain, nodeIDToParams: nodesResp.nodeIDToParams, donToCapabilities: capabilitiesResp.donToCapabilities, - donToOcr2Nodes: donToOcr2Nodes, + donToNodes: donToNodes, }) if err != nil { return nil, fmt.Errorf("failed to register DONS: %w", err) @@ -459,25 +388,20 @@ func ConfigureOCR3ContractFromJD(env *deployment.Environment, cfg ConfigureOCR3C if contract == nil { return nil, fmt.Errorf("no ocr3 contract found for chain %d", cfg.ChainSel) } - nodes, err := NodesFromJD("nodes", cfg.NodeIDs, env.Offchain) + nodes, err := deployment.NodeInfo(cfg.NodeIDs, env.Offchain) if err != nil { return nil, err } - var ocr2nodes []*ocr2Node - for _, node := range nodes { - n, err := newOcr2NodeFromJD(&node, cfg.ChainSel) - if err != nil { - return nil, fmt.Errorf("failed to create ocr2 node from clo node %v: %w", node, err) - } - ocr2nodes = append(ocr2nodes, n) - } r, err := configureOCR3contract(configureOCR3Request{ cfg: cfg.OCR3Config, chain: registryChain, contract: contract, - nodes: ocr2nodes, + nodes: nodes, dryRun: cfg.DryRun, }) + if err != nil { + return nil, err + } return &ConfigureOCR3Resp{ OCR2OracleConfig: r.ocrConfig, }, nil @@ -679,7 +603,7 @@ type registerNodesRequest struct { registry *kcr.CapabilitiesRegistry chain deployment.Chain nopToNodeIDs map[kcr.CapabilitiesRegistryNodeOperator][]string - donToOcr2Nodes map[string][]*ocr2Node + donToNodes map[string][]deployment.Node donToCapabilities map[string][]RegisteredCapability nops []*kcr.CapabilitiesRegistryNodeOperatorAdded } @@ -711,8 +635,18 @@ func registerNodes(lggr logger.Logger, req *registerNodesRequest) (*registerNode } } + // TODO: deduplicate everywhere + registryChainID, err := chainsel.ChainIdFromSelector(req.chain.Selector) + if err != nil { + return nil, err + } + registryChainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(strconv.Itoa(int(registryChainID)), chainsel.FamilyEVM) + if err != nil { + return nil, err + } + nodeIDToParams := make(map[string]kcr.CapabilitiesRegistryNodeParams) - for don, ocr2nodes := range req.donToOcr2Nodes { + for don, nodes := range req.donToNodes { caps, ok := req.donToCapabilities[don] if !ok { return nil, fmt.Errorf("capabilities not found for node operator %s", don) @@ -723,22 +657,30 @@ func registerNodes(lggr logger.Logger, req *registerNodesRequest) (*registerNode } lggr.Debugw("hashed capability ids", "don", don, "ids", hashedCapabilityIds) - for _, n := range ocr2nodes { - if n.IsBoostrap { // bootstraps are part of the DON but don't host capabilities + for _, n := range nodes { + if n.IsBootstrap { // bootstraps are part of the DON but don't host capabilities continue } - nop, ok := nodeToRegisterNop[n.ID] + nop, ok := nodeToRegisterNop[n.NodeID] if !ok { - return nil, fmt.Errorf("node operator not found for node %s", n.ID) + return nil, fmt.Errorf("node operator not found for node %s", n.NodeID) } - params, ok := nodeIDToParams[n.ID] + params, ok := nodeIDToParams[n.NodeID] if !ok { + evmCC, exists := n.SelToOCRConfig[registryChainDetails] + if !exists { + return nil, fmt.Errorf("config for selector not found on node: %v", req.chain.Selector) + } + var signer [32]byte + copy(signer[:], evmCC.OnchainPublicKey) + var csakey [32]byte + copy(csakey[:], evmCC.ConfigEncryptionPublicKey[:]) params = kcr.CapabilitiesRegistryNodeParams{ NodeOperatorId: nop.NodeOperatorId, - Signer: n.Signer, - P2pId: n.P2PKey, - EncryptionPublicKey: n.EncryptionPublicKey, + Signer: signer, + P2pId: n.PeerID, + EncryptionPublicKey: csakey, HashedCapabilityIds: hashedCapabilityIds, } } else { @@ -758,7 +700,7 @@ func registerNodes(lggr logger.Logger, req *registerNodesRequest) (*registerNode } params.HashedCapabilityIds = append(params.HashedCapabilityIds, newCapIds...) } - nodeIDToParams[n.ID] = params + nodeIDToParams[n.NodeID] = params } } @@ -811,7 +753,7 @@ type registerDonsRequest struct { nodeIDToParams map[string]kcr.CapabilitiesRegistryNodeParams donToCapabilities map[string][]RegisteredCapability - donToOcr2Nodes map[string][]*ocr2Node + donToNodes map[string][]deployment.Node } type registerDonsResponse struct { @@ -830,7 +772,7 @@ func sortedHash(p2pids [][32]byte) string { } func registerDons(lggr logger.Logger, req registerDonsRequest) (*registerDonsResponse, error) { - lggr.Infow("registering DONs...", "len", len(req.donToOcr2Nodes)) + lggr.Infow("registering DONs...", "len", len(req.donToNodes)) // track hash of sorted p2pids to don name because the registry return value does not include the don name // and we need to map it back to the don name to access the other mapping data such as the don's capabilities & nodes p2pIdsToDon := make(map[string]string) @@ -847,15 +789,15 @@ func registerDons(lggr logger.Logger, req registerDonsRequest) (*registerDonsRes } lggr.Infow("fetched existing DONs...", "len", len(donInfos), "lenByNodesHash", len(existingDONs)) - for don, ocr2nodes := range req.donToOcr2Nodes { + for don, nodes := range req.donToNodes { var p2pIds [][32]byte - for _, n := range ocr2nodes { - if n.IsBoostrap { + for _, n := range nodes { + if n.IsBootstrap { continue } - params, ok := req.nodeIDToParams[n.ID] + params, ok := req.nodeIDToParams[n.NodeID] if !ok { - return nil, fmt.Errorf("node params not found for non-bootstrap node %s", n.ID) + return nil, fmt.Errorf("node params not found for non-bootstrap node %s", n.NodeID) } p2pIds = append(p2pIds, params.P2pId) } @@ -965,7 +907,8 @@ func configureForwarder(lggr logger.Logger, chain deployment.Chain, fwdr *kf.Key continue } ver := dn.Info.ConfigCount // note config count on the don info is the version on the forwarder - tx, err := fwdr.SetConfig(chain.DeployerKey, dn.Info.Id, ver, dn.Info.F, dn.signers()) + signers := dn.signers(chainsel.FamilyEVM) + tx, err := fwdr.SetConfig(chain.DeployerKey, dn.Info.Id, ver, dn.Info.F, signers) if err != nil { err = DecodeErr(kf.KeystoneForwarderABI, err) return fmt.Errorf("failed to call SetConfig for forwarder %s on chain %d: %w", fwdr.Address().String(), chain.Selector, err) @@ -975,50 +918,7 @@ func configureForwarder(lggr logger.Logger, chain deployment.Chain, fwdr *kf.Key err = DecodeErr(kf.KeystoneForwarderABI, err) return fmt.Errorf("failed to confirm SetConfig for forwarder %s: %w", fwdr.Address().String(), err) } - lggr.Debugw("configured forwarder", "forwarder", fwdr.Address().String(), "donId", dn.Info.Id, "version", ver, "f", dn.Info.F, "signers", dn.signers()) + lggr.Debugw("configured forwarder", "forwarder", fwdr.Address().String(), "donId", dn.Info.Id, "version", ver, "f", dn.Info.F, "signers", signers) } return nil } - -type configureOCR3Request struct { - cfg *OracleConfigWithSecrets - chain deployment.Chain - contract *kocr3.OCR3Capability - nodes []*ocr2Node - dryRun bool -} -type configureOCR3Response struct { - ocrConfig OCR2OracleConfig -} - -func configureOCR3contract(req configureOCR3Request) (*configureOCR3Response, error) { - if req.contract == nil { - return nil, fmt.Errorf("OCR3 contract is nil") - } - nks := makeNodeKeysSlice(req.nodes) - ocrConfig, err := GenerateOCR3Config(*req.cfg, nks) - if err != nil { - return nil, fmt.Errorf("failed to generate OCR3 config: %w", err) - } - if req.dryRun { - return &configureOCR3Response{ocrConfig}, nil - } - tx, err := req.contract.SetConfig(req.chain.DeployerKey, - ocrConfig.Signers, - ocrConfig.Transmitters, - ocrConfig.F, - ocrConfig.OnchainConfig, - ocrConfig.OffchainConfigVersion, - ocrConfig.OffchainConfig, - ) - if err != nil { - err = DecodeErr(kocr3.OCR3CapabilityABI, err) - return nil, fmt.Errorf("failed to call SetConfig for OCR3 contract %s: %w", req.contract.Address().String(), err) - } - _, err = req.chain.Confirm(tx) - if err != nil { - err = DecodeErr(kocr3.OCR3CapabilityABI, err) - return nil, fmt.Errorf("failed to confirm SetConfig for OCR3 contract %s: %w", req.contract.Address().String(), err) - } - return &configureOCR3Response{ocrConfig}, nil -} diff --git a/deployment/keystone/deploy_test.go b/deployment/keystone/deploy_test.go index 4e0d2a52dcc..e446405944c 100644 --- a/deployment/keystone/deploy_test.go +++ b/deployment/keystone/deploy_test.go @@ -8,26 +8,24 @@ import ( "testing" "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/stretchr/testify/assert" - "github.com/test-go/testify/require" - "go.uber.org/zap/zapcore" - "golang.org/x/exp/maps" - chainsel "github.com/smartcontractkit/chain-selectors" - + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/environment/clo" "github.com/smartcontractkit/chainlink/deployment/environment/clo/models" "github.com/smartcontractkit/chainlink/deployment/environment/memory" "github.com/smartcontractkit/chainlink/deployment/keystone" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/smartcontractkit/chainlink/v2/core/logger" + + "github.com/stretchr/testify/assert" + "github.com/test-go/testify/require" + "go.uber.org/zap/zapcore" + "golang.org/x/exp/maps" ) func TestDeploy(t *testing.T) { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) // sepolia; all nodes are on the this chain sepoliaChainId := uint64(11155111) @@ -37,7 +35,8 @@ func TestDeploy(t *testing.T) { require.NoError(t, err) // sepoliaArbitrumChainSel, err := chainsel.SelectorFromChainId(sepoliaArbitrumChainId) // require.NoError(t, err) - // aptosChainSel := uint64(999) // TODO: + // aptos-testnet + aptosChainSel := chainsel.AptosChainIdToChainSelector()[2] crConfig := deployment.CapabilityRegistryConfig{ EVMChainID: sepoliaChainId, @@ -45,11 +44,11 @@ func TestDeploy(t *testing.T) { } evmChains := memory.NewMemoryChainsWithChainIDs(t, []uint64{sepoliaChainId, sepoliaArbitrumChainId}) - // aptosChain := memory.NewMemoryChain(t, aptosChainSel) + aptosChain := memory.NewMemoryChain(t, aptosChainSel) wfChains := map[uint64]deployment.Chain{} wfChains[sepoliaChainSel] = evmChains[sepoliaChainSel] - // wfChains[aptosChainSel] = aptosChain + wfChains[aptosChainSel] = aptosChain wfNodes := memory.NewNodes(t, zapcore.InfoLevel, wfChains, 4, 0, crConfig) require.Len(t, wfNodes, 4) @@ -225,7 +224,7 @@ func nodeOperatorsToIDs(t *testing.T, nops []*models.NodeOperator) (nodeIDs []ke } func TestDeployCLO(t *testing.T) { - lggr := logger.TestLogger(t) + lggr := logger.Test(t) wfNops := loadTestNops(t, "testdata/workflow_nodes.json") cwNops := loadTestNops(t, "testdata/chain_writer_nodes.json") diff --git a/deployment/keystone/ocr3config.go b/deployment/keystone/ocr3config.go index 2c12ae3c596..a281a69ed8a 100644 --- a/deployment/keystone/ocr3config.go +++ b/deployment/keystone/ocr3config.go @@ -17,6 +17,7 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/deployment" + kocr3 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/ocr3_capability" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" @@ -237,3 +238,51 @@ func GenerateOCR3Config(cfg OracleConfigWithSecrets, nca []NodeKeys) (OCR2Oracle return config, nil } + +type configureOCR3Request struct { + cfg *OracleConfigWithSecrets + chain deployment.Chain + contract *kocr3.OCR3Capability + nodes []deployment.Node + dryRun bool +} + +func (r configureOCR3Request) generateOCR3Config() (OCR2OracleConfig, error) { + nks := makeNodeKeysSlice(r.nodes, r.chain.Selector) + return GenerateOCR3Config(*r.cfg, nks) +} + +type configureOCR3Response struct { + ocrConfig OCR2OracleConfig +} + +func configureOCR3contract(req configureOCR3Request) (*configureOCR3Response, error) { + if req.contract == nil { + return nil, fmt.Errorf("OCR3 contract is nil") + } + ocrConfig, err := req.generateOCR3Config() + if err != nil { + return nil, fmt.Errorf("failed to generate OCR3 config: %w", err) + } + if req.dryRun { + return &configureOCR3Response{ocrConfig}, nil + } + tx, err := req.contract.SetConfig(req.chain.DeployerKey, + ocrConfig.Signers, + ocrConfig.Transmitters, + ocrConfig.F, + ocrConfig.OnchainConfig, + ocrConfig.OffchainConfigVersion, + ocrConfig.OffchainConfig, + ) + if err != nil { + err = DecodeErr(kocr3.OCR3CapabilityABI, err) + return nil, fmt.Errorf("failed to call SetConfig for OCR3 contract %s: %w", req.contract.Address().String(), err) + } + _, err = req.chain.Confirm(tx) + if err != nil { + err = DecodeErr(kocr3.OCR3CapabilityABI, err) + return nil, fmt.Errorf("failed to confirm SetConfig for OCR3 contract %s: %w", req.contract.Address().String(), err) + } + return &configureOCR3Response{ocrConfig}, nil +} diff --git a/deployment/keystone/ocr3config_test.go b/deployment/keystone/ocr3config_test.go new file mode 100644 index 00000000000..4046787724a --- /dev/null +++ b/deployment/keystone/ocr3config_test.go @@ -0,0 +1,178 @@ +// TODO: KS-458 copied from https://github.com/smartcontractkit/chainlink/blob/65924811dc53a211613927c814d7f04fd85439a4/core/scripts/keystone/src/88_gen_ocr3_config.go#L1 +// to unblock go mod issues when trying to import the scripts package +package keystone + +import ( + "encoding/json" + "os" + "sort" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/common" + chain_selectors "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/view" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + types2 "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + types3 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/test-go/testify/require" +) + +var wantOCR3Config = `{ + "Signers": [ + "011400b35409a8d4f9a18da55c5b2bb08a3f5f68d44442052000b8834eaa062f0df4ccfe7832253920071ec14dc4f78b13ecdda10b824e2dd3b6", + "0114008258f4c4761cc445333017608044a204fd0c006a052000247d0189f65f58be83a4e7d87ff338aaf8956e9acb9fcc783f34f9edc29d1b40", + "011400d4dcc573e9d24a8b27a07bba670ba3a2ab36e5bb052000ba20d3da9b07663f1e8039081a514649fd61a48be2d241bc63537ee47d028fcd", + "0114006607c140e558631407f33bafbabd103863cee876052000046faf34ebfe42510251e6098bc34fa3dd5f2de38ac07e47f2d1b34ac770639f", + "011400a6f35436cb7bffd615cc47a0a04aa0a78696a1440520001221e131ef21014a6a99ed22376eb869746a3b5e30fd202cf79e44efaeb8c5c2", + "011400657587eb55cecd6f90b97297b611c3024e488cc0052000425d1354a7b8180252a221040c718cac0ba0251c7efe31a2acefbba578dc2153", + "0114004885973b2fcf061d5cdfb8f74c5139bd3056e9da0520004a94c75cb9fe8b1fba86fd4b71ad130943281fdefad10216c46eb2285d60950f", + "011400213803bb9f9715379aaf11aadb0212369701dc0a05200096dc85670c49caa986de4ad288e680e9afb0f5491160dcbb4868ca718e194fc8", + "0114008c2aa1e6fad88a6006dfb116eb866cbad2910314052000bddafb20cc50d89e0ae2f244908c27b1d639615d8186b28c357669de3359f208", + "011400679296b7c1eb4948efcc87efc550940a182e610c0520004fa557850e4d5c21b3963c97414c1f37792700c4d3b8abdb904b765fd47e39bf" + ], + "Transmitters": [ + "0x2877F08d9c5Cc9F401F730Fa418fAE563A9a2FF3", + "0x415aa1E9a1bcB3929ed92bFa1F9735Dc0D45AD31", + "0xCea84bC1881F3cE14BA13Dc3a00DC1Ff3D553fF0", + "0xA9eFB53c513E413762b2Be5299D161d8E6e7278e", + "0x6F5cAb24Fb7412bB516b3468b9F3a9c471d25fE5", + "0xdAd1F3F8ec690cf335D46c50EdA5547CeF875161", + "0x19e10B063a62B1574AE19020A64fDe6419892dA6", + "0x9ad9f3AD49e5aB0F28bD694d211a90297bD90D7f", + "0x31B179dcF8f9036C30f04bE578793e51bF14A39E", + "0x0b04cE574E80Da73191Ec141c0016a54A6404056" + ], + "F": 3, + "OnchainConfig": "0x", + "OffchainConfigVersion": 30, + "OffchainConfig": "0xc80180e497d012d00180e497d012d80180a8d6b907e00180cab5ee01e80180d88ee16ff0010afa01010a82022003dacd15fc96c965c648e3623180de002b71a97cf6eeca9affb91f461dcd6ce1820220255096a3b7ade10e29c648e0b407fc486180464f713446b1da04f013df6179c8820220dba3c61e5f8bec594be481bcaf67ecea0d1c2950edb15b158ce3dbc77877def3820220b4c4993d6c15fee63800db901a8b35fa419057610962caab1c1d7bed557091278202202a4c7dec127fdd8145e48c5edb9467225098bd8c8ad1dade868325b787affbde820220283471ed66d61fbe11f64eff65d738b59a0301c9a4f846280db26c64c9fdd3f8820220aa3419628ea3536783742d17d8adf05681aa6a6bd2b206fbde78c7e5aa38586d82022001496edce35663071d74472e02119432ba059b3904d205e4358014410e4f2be3820220ad08c2a5878cada53521f4e2bb449f191ccca7899246721a0deeea19f7b83f70820220c805572b813a072067eab2087ddbee8aa719090e12890b15c01094f0d3f74a5f8a02008a02008a02008a02008a02008a02008a02008a02008a02008a020098028094ebdc03a0028094ebdc03a8028094ebdc03b0028094ebdc03ba02f8010a20da47a8cc1c10796dd43f98ed113c648625e2e504c16ac5da9c65669e2377241b1220f5beca3bb11406079dc174183105c474c862a73c257ce8b3d9f5ca065e6264691a10805015e4203740495a23e93c1bd06ba81a10ca58ff36ffb0545dc3f800ddd6f8d0481a1076f664639ca8b5209e488895faa5460f1a104a1e89a7f2d8c89158f18856bf289c2a1a10c2f4330787831f419713ad4990e347d31a10fd403ec0797c001a2794b51d6178916d1a10e14fff88fdd3d1554ed861104ddc56a81a10b0284b9817fec2c3066c6f2651d17fc41a10b090233a67d502f78191c9e19a2a032b1a10e483414860bb612af50ee15ce8cd8ef5c00280e497d012c8028094ebdc03" +}` + +var ocr3Cfg = ` +{ + "MaxQueryLengthBytes": 1000000, + "MaxObservationLengthBytes": 1000000, + "MaxReportLengthBytes": 1000000, + "MaxRequestBatchSize": 1000, + "UniqueReports": true, + "DeltaProgressMillis": 5000, + "DeltaResendMillis": 5000, + "DeltaInitialMillis": 5000, + "DeltaRoundMillis": 2000, + "DeltaGraceMillis": 500, + "DeltaCertifiedCommitRequestMillis": 1000, + "DeltaStageMillis": 30000, + "MaxRoundsPerEpoch": 10, + "TransmissionSchedule": [ + 10 + ], + "MaxDurationQueryMillis": 1000, + "MaxDurationObservationMillis": 1000, + "MaxDurationReportMillis": 1000, + "MaxDurationAcceptMillis": 1000, + "MaxDurationTransmitMillis": 1000, + "MaxFaultyOracles": 3 +}` + +func Test_configureOCR3Request_generateOCR3Config(t *testing.T) { + nodes := loadTestData(t, "testdata/testnet_wf_view.json") + + var cfg OracleConfig + err := json.Unmarshal([]byte(ocr3Cfg), &cfg) + require.NoError(t, err) + + r := configureOCR3Request{ + cfg: &OracleConfigWithSecrets{OracleConfig: cfg, OCRSecrets: deployment.XXXGenerateTestOCRSecrets()}, + nodes: nodes, + chain: deployment.Chain{ + Selector: chain_selectors.ETHEREUM_TESTNET_SEPOLIA.Selector, + }, + } + got, err := r.generateOCR3Config() + require.NoError(t, err) + b, err := json.MarshalIndent(got, "", " ") + require.NoError(t, err) + require.Equal(t, wantOCR3Config, string(b)) +} + +func loadTestData(t *testing.T, path string) []deployment.Node { + data, err := os.ReadFile(path) + require.NoError(t, err) + var nodeViews map[string]*view.NopView + err = json.Unmarshal(data, &nodeViews) + require.NoError(t, err) + require.Len(t, nodeViews, 10) + + names := make([]string, 0) + for k := range nodeViews { + names = append(names, k) + } + sort.Strings(names) + + // in general we can map from the view to the node, but we know the test data + var nodes []deployment.Node + //for _, nv := range nodeViews { + for _, name := range names { + nv := nodeViews[name] + node := deployment.Node{ + NodeID: nv.NodeID, + IsBootstrap: nv.IsBootstrap, + SelToOCRConfig: make(map[chain_selectors.ChainDetails]deployment.OCRConfig), + AdminAddr: nv.PayeeAddress, + } + for chain, ocrKey := range nv.OCRKeys { + // TODO: this decoding could be shared with NodeInfo + p, err := p2pkey.MakePeerID(ocrKey.PeerID) + require.NoError(t, err) + + b := common.Hex2Bytes(ocrKey.OffchainPublicKey) + var opk types2.OffchainPublicKey + copy(opk[:], b) + + b = common.Hex2Bytes(ocrKey.ConfigEncryptionPublicKey) + var cpk types3.ConfigEncryptionPublicKey + copy(cpk[:], b) + + var pubkey types3.OnchainPublicKey + if strings.HasPrefix(chain, "ethereum") { + // convert from pubkey to address + pubkey = common.HexToAddress(ocrKey.OnchainPublicKey).Bytes() + } else { + pubkey = common.Hex2Bytes(ocrKey.OnchainPublicKey) + } + + ocrCfg := deployment.OCRConfig{ + KeyBundleID: ocrKey.KeyBundleID, + OffchainPublicKey: opk, + OnchainPublicKey: pubkey, + PeerID: p, + TransmitAccount: types.Account(ocrKey.TransmitAccount), + ConfigEncryptionPublicKey: cpk, + } + var k chain_selectors.ChainDetails + switch chain { + case "aptos-testnet": + k = chain_selectors.ChainDetails{ + ChainSelector: chain_selectors.APTOS_TESTNET.Selector, + ChainName: chain, + } + + case "ethereum-testnet-sepolia": + k = chain_selectors.ChainDetails{ + ChainSelector: chain_selectors.ETHEREUM_TESTNET_SEPOLIA.Selector, + ChainName: chain, + } + default: + t.Fatalf("unexpected chain %s", chain) + } + node.SelToOCRConfig[k] = ocrCfg + } + + nodes = append(nodes, node) + } + require.Len(t, nodes, 10) + return nodes +} diff --git a/deployment/keystone/state.go b/deployment/keystone/state.go index 33200a40e02..68f2ab97a5d 100644 --- a/deployment/keystone/state.go +++ b/deployment/keystone/state.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment" common_v1_0 "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" "github.com/smartcontractkit/chainlink/deployment/keystone/view" diff --git a/deployment/keystone/test/changeset/capability_registry.go b/deployment/keystone/test/changeset/capability_registry.go new file mode 100644 index 00000000000..28ee711dc75 --- /dev/null +++ b/deployment/keystone/test/changeset/capability_registry.go @@ -0,0 +1,87 @@ +package changeset + +import ( + "fmt" + "testing" + + chainsel "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" + "github.com/smartcontractkit/chainlink/deployment/keystone" + "github.com/smartcontractkit/chainlink/deployment/keystone/changeset" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" +) + +type HydrateConfig struct { + ChainID uint64 +} + +// HydrateCapabilityRegistry deploys a new capabilities registry contract and hydrates it with the provided data. +func HydrateCapabilityRegistry(t *testing.T, v v1_0.CapabilityRegistryView, env deployment.Environment, cfg HydrateConfig) (*capabilities_registry.CapabilitiesRegistry, error) { + t.Helper() + chainSelector, err := chainsel.SelectorFromChainId(cfg.ChainID) + if err != nil { + return nil, fmt.Errorf("failed to get chain selector from chain id: %w", err) + } + chain, ok := env.Chains[chainSelector] + if !ok { + return nil, fmt.Errorf("chain with id %d not found", cfg.ChainID) + } + changesetOutput, err := changeset.DeployCapabilityRegistry(env, chainSelector) + if err != nil { + return nil, fmt.Errorf("failed to deploy contract: %w", err) + } + + resp, err := keystone.GetContractSets(env.Logger, &keystone.GetContractSetsRequest{ + Chains: env.Chains, + AddressBook: changesetOutput.AddressBook, + }) + if err != nil { + return nil, fmt.Errorf("failed to get contract sets: %w", err) + } + cs, ok := resp.ContractSets[chainSelector] + if !ok { + return nil, fmt.Errorf("failed to get contract set for chain selector: %d, chain ID: %d", chainSelector, cfg.ChainID) + } + + deployedContract := cs.CapabilitiesRegistry + + nopsParams := v.NopsToNopsParams() + tx, err := deployedContract.AddNodeOperators(chain.DeployerKey, nopsParams) + if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { + return nil, fmt.Errorf("failed to add node operators: %w", err) + } + + capabilitiesParams := v.CapabilitiesToCapabilitiesParams() + tx, err = deployedContract.AddCapabilities(chain.DeployerKey, capabilitiesParams) + if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { + return nil, fmt.Errorf("failed to add capabilities: %w", err) + } + + nodesParams, err := v.NodesToNodesParams() + if err != nil { + return nil, fmt.Errorf("failed to convert nodes to nodes params: %w", err) + } + tx, err = deployedContract.AddNodes(chain.DeployerKey, nodesParams) + if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { + return nil, fmt.Errorf("failed to add nodes: %w", err) + } + + for _, don := range v.Dons { + cfgs, err := v.CapabilityConfigToCapabilityConfigParams(don) + if err != nil { + return nil, fmt.Errorf("failed to convert capability configurations to capability configuration params: %w", err) + } + var peerIds [][32]byte + for _, id := range don.NodeP2PIds { + peerIds = append(peerIds, id) + } + tx, err = deployedContract.AddDON(chain.DeployerKey, peerIds, cfgs, don.IsPublic, don.AcceptsWorkflows, don.F) + if _, err = deployment.ConfirmIfNoError(chain, tx, keystone.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { + return nil, fmt.Errorf("failed to add don: %w", err) + } + } + + return deployedContract, nil +} diff --git a/deployment/keystone/test/changeset/capability_registry_test.go b/deployment/keystone/test/changeset/capability_registry_test.go new file mode 100644 index 00000000000..765c95ff294 --- /dev/null +++ b/deployment/keystone/test/changeset/capability_registry_test.go @@ -0,0 +1,46 @@ +package changeset + +import ( + "encoding/json" + "os" + "testing" + + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + chainsel "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink/deployment/common/view/v1_0" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +func TestHydrateCapabilityRegistry(t *testing.T) { + b, err := os.ReadFile("testdata/capability_registry_view.json") + require.NoError(t, err) + require.NotEmpty(t, b) + var capabilityRegistryView v1_0.CapabilityRegistryView + require.NoError(t, json.Unmarshal(b, &capabilityRegistryView)) + + chainID := chainsel.TEST_90000001.EvmChainID + cfg := HydrateConfig{ChainID: chainID} + env := memory.NewMemoryEnvironment(t, logger.TestLogger(t), zapcore.InfoLevel, memory.MemoryEnvironmentConfig{ + Bootstraps: 1, + Chains: 1, + Nodes: 4, + }) + hydrated, err := HydrateCapabilityRegistry(t, capabilityRegistryView, env, cfg) + require.NoError(t, err) + require.NotNil(t, hydrated) + hydratedCapView, err := v1_0.GenerateCapabilityRegistryView(hydrated) + require.NoError(t, err) + + // Setting address/owner values to be the same in order to compare the views + hydratedCapView.Address = capabilityRegistryView.Address + hydratedCapView.Owner = capabilityRegistryView.Owner + b1, err := capabilityRegistryView.MarshalJSON() + require.NoError(t, err) + b2, err := hydratedCapView.MarshalJSON() + require.NoError(t, err) + require.Equal(t, string(b1), string(b2)) +} diff --git a/deployment/keystone/test/changeset/testdata/capability_registry_view.json b/deployment/keystone/test/changeset/testdata/capability_registry_view.json new file mode 100644 index 00000000000..fef22a7b4dc --- /dev/null +++ b/deployment/keystone/test/changeset/testdata/capability_registry_view.json @@ -0,0 +1,455 @@ +{ + "typeAndVersion": "CapabilitiesRegistry 1.1.0", + "address": "0x65a097a74769fe1c415993f45d9b56ffffb65807", + "owner": "0x61050aeba13a5f7ba0b06cac4e1aee625fe4a640", + "capabilities": [ + { + "id": "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483", + "labelled_name": "write_ethereum-testnet-sepolia", + "version": "1.0.0", + "capability_type": 3, + "response_type": 0, + "configuration_contract": "0x0000000000000000000000000000000000000000" + }, + { + "id": "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a", + "labelled_name": "streams-trigger", + "version": "1.0.0", + "capability_type": 0, + "response_type": 0, + "configuration_contract": "0x0000000000000000000000000000000000000000" + }, + { + "id": "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b", + "labelled_name": "offchain_reporting", + "version": "1.0.0", + "capability_type": 2, + "response_type": 0, + "configuration_contract": "0x0000000000000000000000000000000000000000" + } + ], + "nodes": [ + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "f36818345fb18549bd24305c79f2f28d80d25710000000000000000000000000", + "p2p_id": "p2p_12D3KooWGVWpMrCZDotqSYWj8xqb1i5kNecpoarczpQoSAHdqwj8", + "encryption_public_key": "986707930499b85ab01705aa8d5cd99dca40926db3fa1728e6b58d25fddfe46b", + "node_operator_id": 1, + "capability_ids": [ + "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b" + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "a0e11229b4b5d40d299f7f4b3348a1b16f5f3dd3000000000000000000000000", + "p2p_id": "p2p_12D3KooWPsGKEe34m9X8qiWVpa6VEcjdvhbygJRLKXdVEr3r96PH", + "encryption_public_key": "10c77049880fe0924f463763789985a0f76e09f82fc6f39943684b2dd05b98bf", + "node_operator_id": 2, + "capability_ids": [ + "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483" + ], + "capability_don_ids": [ + 2 + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "3f871cd7c34e50320934b6ba9b90b249363fd378000000000000000000000000", + "p2p_id": "p2p_12D3KooWLjKKWLhYkr68PH9FaZZR93WbJuohWWcTfA9JeY1UPoJa", + "encryption_public_key": "5cf5abd0349b27cde43ad1a55aa3b02a5518aa6eed365bd65ca5e0e2cbfdaa5a", + "node_operator_id": 3, + "capability_ids": [ + "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a" + ], + "capability_don_ids": [ + 3 + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "d7a432ce8f23c410302e7577de9973ccbca29576000000000000000000000000", + "p2p_id": "p2p_12D3KooWRG3rsPdQyWCPsQukUF5JqFLdPqVVXvEfG2PAPBbqdRXp", + "encryption_public_key": "c10cead34374ba20704a05ca0369018b41778a0297adb85554cdd6e5955bf4b6", + "node_operator_id": 3, + "capability_ids": [ + "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a" + ], + "capability_don_ids": [ + 3 + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "f1d2b3d13c46b0c1ded96534aabd6bae61934e3f000000000000000000000000", + "p2p_id": "p2p_12D3KooWD1uj8Y9Phdr1yScfbBy1Q9ebedMVBjMUBLW4m4XnEzGF", + "encryption_public_key": "5fc3dae131da5b0ac5474ad029e3a6c547e17249a6266427d5eea1f529b6488b", + "node_operator_id": 3, + "capability_ids": [ + "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a" + ], + "capability_don_ids": [ + 3 + ] + }, + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "afabd7685010d619ee6614e732b15e898c293426000000000000000000000000", + "p2p_id": "p2p_12D3KooWE8ymezL2wxXcZdhznnBkVNcBRbtxVfNx1vppu7Z7zfnd", + "encryption_public_key": "8a2aef988ccc85d985d12270c5263032b9a7c71a86430e7b3c30a2f493462aee", + "node_operator_id": 1, + "capability_ids": [ + "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b" + ] + }, + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "4bad6c33b85ba3bbbada74c93a7a719962456af8000000000000000000000000", + "p2p_id": "p2p_12D3KooWSEF7cqkbMrS6uCo6xzCsfcPgquN652mZijmay8e3pn5R", + "encryption_public_key": "cf8e0e8c830f733dd5992076d0adaeb34c97410dd5d8d04afccad88070b07f20", + "node_operator_id": 1, + "capability_ids": [ + "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b" + ] + }, + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "078cb3bca763a11a0c79df636b018311d9e36954000000000000000000000000", + "p2p_id": "p2p_12D3KooWAumheDZJdc3in1qiYGAQESTUm1nAWGA59eQPb3wuFHJa", + "encryption_public_key": "c8f45b74982037dd52eeb3df5295c7769757c72cde9a930fc82cb72caf0085ad", + "node_operator_id": 1, + "capability_ids": [ + "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b" + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "7621630d4f33e02f659445974060df375c126e82000000000000000000000000", + "p2p_id": "p2p_12D3KooWF1XmgvoLx45H3iGc9jD4mK7X1mctYmhZCqw5h1S1sXtA", + "encryption_public_key": "f8d7485910b56c9521dea1beb3d50151917bae18e131ad311ef90300318b8110", + "node_operator_id": 2, + "capability_ids": [ + "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483" + ], + "capability_don_ids": [ + 2 + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "b5599a0a8aa99860997e42d650c3dc1ac767a4b1000000000000000000000000", + "p2p_id": "p2p_12D3KooWFBsQE8gCZndyefzCZG6KHyjoeii7o7ff171tQHsGYq1p", + "encryption_public_key": "4081aacba87f07ea54c32517a9b661963a5fed5fbfd2042ff0823293d8fbd523", + "node_operator_id": 2, + "capability_ids": [ + "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483" + ], + "capability_don_ids": [ + 2 + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "2067cc4ec71978974265e578eb9b5c62cccc0d33000000000000000000000000", + "p2p_id": "p2p_12D3KooWKYQ51iqiS99MWfE8gwy7P1sN8oL4WboWLPxHRo8duc28", + "encryption_public_key": "533bfbd913615823cbb93251f27f3cbdd035a732c0a68ad49081b37a702fe4a1", + "node_operator_id": 2, + "capability_ids": [ + "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483" + ], + "capability_don_ids": [ + 2 + ] + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "cd08a4d5934c41a389c2bd7b6fadfb1dace5f110000000000000000000000000", + "p2p_id": "p2p_12D3KooWMQjP7pp8ecxMSMd3Y3NocDsHt7g64bd7iGJhCr35gkby", + "encryption_public_key": "9ee181448ef55e381217ec959375fb302eba62e61006e4c9467832836cc8640e", + "node_operator_id": 3, + "capability_ids": [ + "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a" + ], + "capability_don_ids": [ + 3 + ] + } + ], + "nops": [ + { + "admin": "0x528fdfde37119b52010a4920b09ef828249a3434", + "name": "nop 1" + }, + { + "admin": "0xe0967f1d0f36df4c53a34e491465c9d3f0095eb9", + "name": "nop 2" + }, + { + "admin": "0xe676a607b6f5c0b6d4c21aa616d727d5b0a47f35", + "name": "nop 3" + } + ], + "dons": [ + { + "id": 1, + "config_count": 1, + "f": 1, + "is_public": true, + "accepts_workflows": true, + "node_p2p_ids": [ + "p2p_12D3KooWAumheDZJdc3in1qiYGAQESTUm1nAWGA59eQPb3wuFHJa", + "p2p_12D3KooWE8ymezL2wxXcZdhznnBkVNcBRbtxVfNx1vppu7Z7zfnd", + "p2p_12D3KooWGVWpMrCZDotqSYWj8xqb1i5kNecpoarczpQoSAHdqwj8", + "p2p_12D3KooWSEF7cqkbMrS6uCo6xzCsfcPgquN652mZijmay8e3pn5R" + ], + "capability_configurations": [ + { + "id": "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b", + "config": "0a00" + } + ] + }, + { + "id": 2, + "config_count": 1, + "f": 1, + "is_public": true, + "node_p2p_ids": [ + "p2p_12D3KooWF1XmgvoLx45H3iGc9jD4mK7X1mctYmhZCqw5h1S1sXtA", + "p2p_12D3KooWFBsQE8gCZndyefzCZG6KHyjoeii7o7ff171tQHsGYq1p", + "p2p_12D3KooWKYQ51iqiS99MWfE8gwy7P1sN8oL4WboWLPxHRo8duc28", + "p2p_12D3KooWPsGKEe34m9X8qiWVpa6VEcjdvhbygJRLKXdVEr3r96PH" + ], + "capability_configurations": [ + { + "id": "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483", + "config": "0a001a1a0a187369676e65645f7265706f72742e5369676e617475726573" + } + ] + }, + { + "id": 3, + "config_count": 1, + "f": 1, + "is_public": true, + "node_p2p_ids": [ + "p2p_12D3KooWD1uj8Y9Phdr1yScfbBy1Q9ebedMVBjMUBLW4m4XnEzGF", + "p2p_12D3KooWLjKKWLhYkr68PH9FaZZR93WbJuohWWcTfA9JeY1UPoJa", + "p2p_12D3KooWMQjP7pp8ecxMSMd3Y3NocDsHt7g64bd7iGJhCr35gkby", + "p2p_12D3KooWRG3rsPdQyWCPsQukUF5JqFLdPqVVXvEfG2PAPBbqdRXp" + ], + "capability_configurations": [ + { + "id": "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a", + "config": "0a00120a0a0208141202083c1802" + } + ] + } + ], + "don_capabilities_summary": [ + { + "don": { + "id": 1, + "config_count": 1, + "f": 1, + "is_public": true, + "accepts_workflows": true + }, + "nodes": [ + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "f36818345fb18549bd24305c79f2f28d80d25710000000000000000000000000", + "p2p_id": "p2p_12D3KooWGVWpMrCZDotqSYWj8xqb1i5kNecpoarczpQoSAHdqwj8", + "encryption_public_key": "986707930499b85ab01705aa8d5cd99dca40926db3fa1728e6b58d25fddfe46b", + "nop": { + "admin": "0x528fdfde37119b52010a4920b09ef828249a3434", + "name": "nop 1" + } + }, + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "afabd7685010d619ee6614e732b15e898c293426000000000000000000000000", + "p2p_id": "p2p_12D3KooWE8ymezL2wxXcZdhznnBkVNcBRbtxVfNx1vppu7Z7zfnd", + "encryption_public_key": "8a2aef988ccc85d985d12270c5263032b9a7c71a86430e7b3c30a2f493462aee", + "nop": { + "admin": "0x528fdfde37119b52010a4920b09ef828249a3434", + "name": "nop 1" + } + }, + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "4bad6c33b85ba3bbbada74c93a7a719962456af8000000000000000000000000", + "p2p_id": "p2p_12D3KooWSEF7cqkbMrS6uCo6xzCsfcPgquN652mZijmay8e3pn5R", + "encryption_public_key": "cf8e0e8c830f733dd5992076d0adaeb34c97410dd5d8d04afccad88070b07f20", + "nop": { + "admin": "0x528fdfde37119b52010a4920b09ef828249a3434", + "name": "nop 1" + } + }, + { + "config_count": 1, + "workflow_don_id": 1, + "signer": "078cb3bca763a11a0c79df636b018311d9e36954000000000000000000000000", + "p2p_id": "p2p_12D3KooWAumheDZJdc3in1qiYGAQESTUm1nAWGA59eQPb3wuFHJa", + "encryption_public_key": "c8f45b74982037dd52eeb3df5295c7769757c72cde9a930fc82cb72caf0085ad", + "nop": { + "admin": "0x528fdfde37119b52010a4920b09ef828249a3434", + "name": "nop 1" + } + } + ], + "capabilities": [ + { + "id": "578ebf7413c15e36dfd792396c5a4d75c43f0ee7bbabdb703f7c5acd0bb65a1b", + "labelled_name": "offchain_reporting", + "version": "1.0.0", + "capability_type": 2, + "response_type": 0, + "configuration_contract": "0x0000000000000000000000000000000000000000" + } + ] + }, + { + "don": { + "id": 2, + "config_count": 1, + "f": 1, + "is_public": true + }, + "nodes": [ + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "a0e11229b4b5d40d299f7f4b3348a1b16f5f3dd3000000000000000000000000", + "p2p_id": "p2p_12D3KooWPsGKEe34m9X8qiWVpa6VEcjdvhbygJRLKXdVEr3r96PH", + "encryption_public_key": "10c77049880fe0924f463763789985a0f76e09f82fc6f39943684b2dd05b98bf", + "nop": { + "admin": "0xe0967f1d0f36df4c53a34e491465c9d3f0095eb9", + "name": "nop 2" + } + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "7621630d4f33e02f659445974060df375c126e82000000000000000000000000", + "p2p_id": "p2p_12D3KooWF1XmgvoLx45H3iGc9jD4mK7X1mctYmhZCqw5h1S1sXtA", + "encryption_public_key": "f8d7485910b56c9521dea1beb3d50151917bae18e131ad311ef90300318b8110", + "nop": { + "admin": "0xe0967f1d0f36df4c53a34e491465c9d3f0095eb9", + "name": "nop 2" + } + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "b5599a0a8aa99860997e42d650c3dc1ac767a4b1000000000000000000000000", + "p2p_id": "p2p_12D3KooWFBsQE8gCZndyefzCZG6KHyjoeii7o7ff171tQHsGYq1p", + "encryption_public_key": "4081aacba87f07ea54c32517a9b661963a5fed5fbfd2042ff0823293d8fbd523", + "nop": { + "admin": "0xe0967f1d0f36df4c53a34e491465c9d3f0095eb9", + "name": "nop 2" + } + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "2067cc4ec71978974265e578eb9b5c62cccc0d33000000000000000000000000", + "p2p_id": "p2p_12D3KooWKYQ51iqiS99MWfE8gwy7P1sN8oL4WboWLPxHRo8duc28", + "encryption_public_key": "533bfbd913615823cbb93251f27f3cbdd035a732c0a68ad49081b37a702fe4a1", + "nop": { + "admin": "0xe0967f1d0f36df4c53a34e491465c9d3f0095eb9", + "name": "nop 2" + } + } + ], + "capabilities": [ + { + "id": "9f0f33d3737af0a2acae89e7f8c4638aeb886a67c1d84e13aee8532c70aa9483", + "labelled_name": "write_ethereum-testnet-sepolia", + "version": "1.0.0", + "capability_type": 3, + "response_type": 0, + "configuration_contract": "0x0000000000000000000000000000000000000000" + } + ] + }, + { + "don": { + "id": 3, + "config_count": 1, + "f": 1, + "is_public": true + }, + "nodes": [ + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "3f871cd7c34e50320934b6ba9b90b249363fd378000000000000000000000000", + "p2p_id": "p2p_12D3KooWLjKKWLhYkr68PH9FaZZR93WbJuohWWcTfA9JeY1UPoJa", + "encryption_public_key": "5cf5abd0349b27cde43ad1a55aa3b02a5518aa6eed365bd65ca5e0e2cbfdaa5a", + "nop": { + "admin": "0xe676a607b6f5c0b6d4c21aa616d727d5b0a47f35", + "name": "nop 3" + } + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "d7a432ce8f23c410302e7577de9973ccbca29576000000000000000000000000", + "p2p_id": "p2p_12D3KooWRG3rsPdQyWCPsQukUF5JqFLdPqVVXvEfG2PAPBbqdRXp", + "encryption_public_key": "c10cead34374ba20704a05ca0369018b41778a0297adb85554cdd6e5955bf4b6", + "nop": { + "admin": "0xe676a607b6f5c0b6d4c21aa616d727d5b0a47f35", + "name": "nop 3" + } + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "f1d2b3d13c46b0c1ded96534aabd6bae61934e3f000000000000000000000000", + "p2p_id": "p2p_12D3KooWD1uj8Y9Phdr1yScfbBy1Q9ebedMVBjMUBLW4m4XnEzGF", + "encryption_public_key": "5fc3dae131da5b0ac5474ad029e3a6c547e17249a6266427d5eea1f529b6488b", + "nop": { + "admin": "0xe676a607b6f5c0b6d4c21aa616d727d5b0a47f35", + "name": "nop 3" + } + }, + { + "config_count": 1, + "workflow_don_id": 0, + "signer": "cd08a4d5934c41a389c2bd7b6fadfb1dace5f110000000000000000000000000", + "p2p_id": "p2p_12D3KooWMQjP7pp8ecxMSMd3Y3NocDsHt7g64bd7iGJhCr35gkby", + "encryption_public_key": "9ee181448ef55e381217ec959375fb302eba62e61006e4c9467832836cc8640e", + "nop": { + "admin": "0xe676a607b6f5c0b6d4c21aa616d727d5b0a47f35", + "name": "nop 3" + } + } + ], + "capabilities": [ + { + "id": "1ea6e85dfb8ebb08b7cd82b42ab4655429a8ae116d513be0d68a7d7661667a8a", + "labelled_name": "streams-trigger", + "version": "1.0.0", + "capability_type": 0, + "response_type": 0, + "configuration_contract": "0x0000000000000000000000000000000000000000" + } + ] + } + ] +} \ No newline at end of file diff --git a/deployment/keystone/testdata/testnet_wf_view.json b/deployment/keystone/testdata/testnet_wf_view.json new file mode 100644 index 00000000000..8a4162f5e58 --- /dev/null +++ b/deployment/keystone/testdata/testnet_wf_view.json @@ -0,0 +1,262 @@ +{ + "cl-keystone-one-0": { + "nodeID": "node_00", + "isBootstrap": false, + "ocrKeys": { + "aptos-testnet": { + "offchainPublicKey": "4ec55bbe76a6b1fdc885c59da85a8fe44cf06afe1e4719f0824a731937526c52", + "onchainPublicKey": "b8834eaa062f0df4ccfe7832253920071ec14dc4f78b13ecdda10b824e2dd3b6", + "peerID": "p2p_12D3KooWMWUKdoAc2ruZf9f55p7NVFj7AFiPm67xjQ8BZBwkqyYv", + "transmitAccount": " ", + "configEncryptionPublicKey": "559ea4ee5774a31d97914a4220d6a47094ae8e2cf0806e80e1eacd851f3e6757", + "keyBundleID": "b4504e84ea307cc2afffca0206bd4bf8e98acc5a03c9bd47b2456e3845a5d1fa" + }, + "ethereum-testnet-sepolia": { + "offchainPublicKey": "03dacd15fc96c965c648e3623180de002b71a97cf6eeca9affb91f461dcd6ce1", + "onchainPublicKey": "b35409a8d4f9a18da55c5b2bb08a3f5f68d44442", + "peerID": "p2p_12D3KooWMWUKdoAc2ruZf9f55p7NVFj7AFiPm67xjQ8BZBwkqyYv", + "transmitAccount": "0x2877F08d9c5Cc9F401F730Fa418fAE563A9a2FF3", + "configEncryptionPublicKey": "5193f72fc7b4323a86088fb0acb4e4494ae351920b3944bd726a59e8dbcdd45f", + "keyBundleID": "665a101d79d310cb0a5ebf695b06e8fc8082b5cbe62d7d362d80d47447a31fea" + } + }, + "payeeAddress": "", + "csaKey": "403b72f0b1b3b5f5a91bcfedb7f28599767502a04b5b7e067fcf3782e23eeb9c", + "isConnected": true, + "isEnabled": true + }, + "cl-keystone-one-1": { + "nodeID": "node_01", + "isBootstrap": false, + "ocrKeys": { + "aptos-testnet": { + "offchainPublicKey": "a38dbe521643479d78ab5477cae78161a5de0030c95098e3fbb09add6aca9508", + "onchainPublicKey": "247d0189f65f58be83a4e7d87ff338aaf8956e9acb9fcc783f34f9edc29d1b40", + "peerID": "p2p_12D3KooWCbDiL7sP9BVby5KaZqPpaVP1RBokoa9ShzH5WhkYX46v", + "transmitAccount": " ", + "configEncryptionPublicKey": "a38dbe521643479d78ab5477cae78161a5de0030c95098e3fbb09add6aca9508", + "keyBundleID": "4b6418b8ab88ea1244c3c48eb5f4c86f9f0301aebffcac4fcfac5cdfb7cf6933" + }, + "ethereum-testnet-sepolia": { + "offchainPublicKey": "255096a3b7ade10e29c648e0b407fc486180464f713446b1da04f013df6179c8", + "onchainPublicKey": "8258f4c4761cc445333017608044a204fd0c006a", + "peerID": "p2p_12D3KooWCbDiL7sP9BVby5KaZqPpaVP1RBokoa9ShzH5WhkYX46v", + "transmitAccount": "0x415aa1E9a1bcB3929ed92bFa1F9735Dc0D45AD31", + "configEncryptionPublicKey": "2c45fec2320f6bcd36444529a86d9f8b4439499a5d8272dec9bcbbebb5e1bf01", + "keyBundleID": "7a9b75510b8d09932b98142419bef52436ff725dd9395469473b487ef87fdfb0" + } + }, + "payeeAddress": "", + "csaKey": "28b91143ec9111796a7d63e14c1cf6bb01b4ed59667ab54f5bc72ebe49c881be", + "isConnected": true, + "isEnabled": true + }, + "cl-keystone-one-2": { + "nodeID": "node_MgvchYopDVSBv3BCpNgEk", + "isBootstrap": false, + "ocrKeys": { + "aptos-testnet": { + "offchainPublicKey": "450aa794c87198a595761a8c18f0f1590046c8092960036638d002256af95254", + "onchainPublicKey": "ba20d3da9b07663f1e8039081a514649fd61a48be2d241bc63537ee47d028fcd", + "peerID": "p2p_12D3KooWGDmBKZ7B3PynGrvfHTJMEecpjfHts9YK5NWk8oJuxcAo", + "transmitAccount": " ", + "configEncryptionPublicKey": "412a4bed6b064c17168871d28dbb965cc0a898f7b19eb3fa7cd01d3e3d10b66c", + "keyBundleID": "e57c608a899d80e510913d2c7ef55758ee81e9eb73eb531003af1564307fd133" + }, + "ethereum-testnet-sepolia": { + "offchainPublicKey": "dba3c61e5f8bec594be481bcaf67ecea0d1c2950edb15b158ce3dbc77877def3", + "onchainPublicKey": "d4dcc573e9d24a8b27a07bba670ba3a2ab36e5bb", + "peerID": "p2p_12D3KooWGDmBKZ7B3PynGrvfHTJMEecpjfHts9YK5NWk8oJuxcAo", + "transmitAccount": "0xCea84bC1881F3cE14BA13Dc3a00DC1Ff3D553fF0", + "configEncryptionPublicKey": "ee466234b3b2f65b13c848b17aa6a8d4e0aa0311d3bf8e77a64f20b04ed48d39", + "keyBundleID": "1d20490fe469dd6af3d418cc310a6e835181fa13e8dc80156bcbe302b7afcd34" + } + }, + "payeeAddress": "", + "csaKey": "7a166fbc816eb4a4dcb620d11c3ccac5c085d56b1972374100116f87619debb8", + "isConnected": true, + "isEnabled": true + }, + "cl-keystone-one-3": { + "nodeID": "node_Q9CZrC45VZZkMnCbDNgzH", + "isBootstrap": false, + "ocrKeys": { + "aptos-testnet": { + "offchainPublicKey": "886044b333af681ab4bf3be663122524ece9725e110ac2a64cda8526cad6983e", + "onchainPublicKey": "046faf34ebfe42510251e6098bc34fa3dd5f2de38ac07e47f2d1b34ac770639f", + "peerID": "p2p_12D3KooWCcVLytqinD8xMn27NvomcQhj2mqMVzyGemz6oPwv1SMT", + "transmitAccount": " ", + "configEncryptionPublicKey": "a7f3435bfbaabebd1572142ff1aec9ed98758d9bb098f1fcc77262fcae7f4171", + "keyBundleID": "5811a96a0c3b5f5b52973eee10e5771cf5953d37d5616ea71f7ae76f09f6e332" + }, + "ethereum-testnet-sepolia": { + "offchainPublicKey": "b4c4993d6c15fee63800db901a8b35fa419057610962caab1c1d7bed55709127", + "onchainPublicKey": "6607c140e558631407f33bafbabd103863cee876", + "peerID": "p2p_12D3KooWCcVLytqinD8xMn27NvomcQhj2mqMVzyGemz6oPwv1SMT", + "transmitAccount": "0xA9eFB53c513E413762b2Be5299D161d8E6e7278e", + "configEncryptionPublicKey": "63375a3d175364bd299e7cecf352cb3e469dd30116cf1418f2b7571fb46c4a4b", + "keyBundleID": "8843b5db0608f92dac38ca56775766a08db9ee82224a19595d04bd6c58b38fbd" + } + }, + "payeeAddress": "", + "csaKey": "487901e0c0a9d3c66e7cfc50f3a9e3cdbfdf1b0107273d73d94a91d278545516", + "isConnected": true, + "isEnabled": true + }, + "cl-keystone-one-4": { + "nodeID": "node_q9CQHG4n4QozxAz5UCufa", + "isBootstrap": false, + "ocrKeys": { + "aptos-testnet": { + "offchainPublicKey": "b34bb49788541de8b6cfb321799a41927a391a4eb135c74f6cb14eec0531ee6f", + "onchainPublicKey": "1221e131ef21014a6a99ed22376eb869746a3b5e30fd202cf79e44efaeb8c5c2", + "peerID": "p2p_12D3KooWHqR1w26yHatTSZQW3xbRct9SxWzVj9X4SpU916Hy8jYg", + "transmitAccount": " ", + "configEncryptionPublicKey": "96ae354418e50dcd5b3dae62e8f0bc911bbce7f761220837aacdaa6f82bd0f29", + "keyBundleID": "b1ab478c1322bc4f8227be50898a8044efc70cf0156ec53cf132119db7e94dea" + }, + "ethereum-testnet-sepolia": { + "offchainPublicKey": "2a4c7dec127fdd8145e48c5edb9467225098bd8c8ad1dade868325b787affbde", + "onchainPublicKey": "a6f35436cb7bffd615cc47a0a04aa0a78696a144", + "peerID": "p2p_12D3KooWHqR1w26yHatTSZQW3xbRct9SxWzVj9X4SpU916Hy8jYg", + "transmitAccount": "0x6F5cAb24Fb7412bB516b3468b9F3a9c471d25fE5", + "configEncryptionPublicKey": "c812eab2415f45cc1d2afdb2be2e3ea419bb7851acfc30c07b4df42c856e8f74", + "keyBundleID": "8e563a16ec5a802345b162d0f31149e8d5055014a31847d7b20d6de500aa48bd" + } + }, + "payeeAddress": "", + "csaKey": "07e0ffc57b6263604df517b94bd986169451a3c90600a855bb19212dc575de54", + "isConnected": true, + "isEnabled": true + }, + "cl-keystone-one-5": { + "nodeID": "node_sS3MELvKpNQBMqh7t5QL5", + "isBootstrap": false, + "ocrKeys": { + "aptos-testnet": { + "offchainPublicKey": "11674b98849d8e070ac69d37c284b3091fcd374913f52b2b83ce2d9a4a4e0213", + "onchainPublicKey": "425d1354a7b8180252a221040c718cac0ba0251c7efe31a2acefbba578dc2153", + "peerID": "p2p_12D3KooWR8d5kbZb7YiQWKpT1J1PfMqNaGAmb4jBFx9DWag4hpSZ", + "transmitAccount": " ", + "configEncryptionPublicKey": "263bee0d09d90e0e618c4cdd630d1437f7377f2d544df57f39ddd47984970555", + "keyBundleID": "44b5f46bfbb04d0984469298ec43c350ec6b2cd4556b18265ebac1b6cc329c7c" + }, + "ethereum-testnet-sepolia": { + "offchainPublicKey": "283471ed66d61fbe11f64eff65d738b59a0301c9a4f846280db26c64c9fdd3f8", + "onchainPublicKey": "657587eb55cecd6f90b97297b611c3024e488cc0", + "peerID": "p2p_12D3KooWR8d5kbZb7YiQWKpT1J1PfMqNaGAmb4jBFx9DWag4hpSZ", + "transmitAccount": "0xdAd1F3F8ec690cf335D46c50EdA5547CeF875161", + "configEncryptionPublicKey": "36de4924cf11938b4461aea1ce99cb640e9603d9a7c294ab6c54acd51d575a49", + "keyBundleID": "99fad0362cc8dc8a57a8e616e68133a6d5a8834e08a1b4819710f0e912df5abc" + } + }, + "payeeAddress": "", + "csaKey": "4542f4fd2ed150c8c976b39802fe3d994aec3ac94fd11e7817f693b1c9a1dabb", + "isConnected": true, + "isEnabled": true + }, + "cl-keystone-one-6": { + "nodeID": "node_jb1oicMu3xxx2N2e4JWvE", + "isBootstrap": false, + "ocrKeys": { + "aptos-testnet": { + "offchainPublicKey": "6fc8c3fb55b39577abbab20028bee93d1d6d8a888dd298354b95d4af3ccb6009", + "onchainPublicKey": "4a94c75cb9fe8b1fba86fd4b71ad130943281fdefad10216c46eb2285d60950f", + "peerID": "p2p_12D3KooWNJ8de3PUURZ2oucrVTpnRTqNBTUYwHLQjK9LzN3E6Mfn", + "transmitAccount": " ", + "configEncryptionPublicKey": "3ae1a1c713e4ad63f67191fd93620c9eebe44e1d5f3264036ec0fbcd59cf9664", + "keyBundleID": "b419e9e3f1256aa2907a1a396bdf27ba5002a30eee440ab96cb60369429ce277" + }, + "ethereum-testnet-sepolia": { + "offchainPublicKey": "aa3419628ea3536783742d17d8adf05681aa6a6bd2b206fbde78c7e5aa38586d", + "onchainPublicKey": "4885973b2fcf061d5cdfb8f74c5139bd3056e9da", + "peerID": "p2p_12D3KooWNJ8de3PUURZ2oucrVTpnRTqNBTUYwHLQjK9LzN3E6Mfn", + "transmitAccount": "0x19e10B063a62B1574AE19020A64fDe6419892dA6", + "configEncryptionPublicKey": "8c6c7d889ac6cc9e663ae48073bbf130fae105d6a3689636db27752e3e3e6816", + "keyBundleID": "62d36269d916b4834b17dc6d637c1c39b0895396249a0845764c898e83f63525" + } + }, + "payeeAddress": "", + "csaKey": "75ac63fc97a31e31168084e0de8ccd2bea90059b609d962f3e43fc296cdba28d", + "isConnected": true, + "isEnabled": true + }, + "cl-keystone-one-7": { + "nodeID": "node_nokJcFtJ5hunVbgLXufKn", + "isBootstrap": false, + "ocrKeys": { + "aptos-testnet": { + "offchainPublicKey": "cf0684a0e59399fe9b92cfc740d9696f925e78ee7d0273947e5f7b830070eaaa", + "onchainPublicKey": "96dc85670c49caa986de4ad288e680e9afb0f5491160dcbb4868ca718e194fc8", + "peerID": "p2p_12D3KooWQMCj73V5xmCd6C5VsJr7rbFG2TF9LwVcLiiBqXps9MgC", + "transmitAccount": " ", + "configEncryptionPublicKey": "209eea27e73b0ecc1c49b3ea274e4a18a1f5ed62fd79f443f0b5b9cc6019356e", + "keyBundleID": "14082da0f33b4cec842bc1e1002e617a194ed4a81105603bd6c1edf784aa3743" + }, + "ethereum-testnet-sepolia": { + "offchainPublicKey": "01496edce35663071d74472e02119432ba059b3904d205e4358014410e4f2be3", + "onchainPublicKey": "213803bb9f9715379aaf11aadb0212369701dc0a", + "peerID": "p2p_12D3KooWQMCj73V5xmCd6C5VsJr7rbFG2TF9LwVcLiiBqXps9MgC", + "transmitAccount": "0x9ad9f3AD49e5aB0F28bD694d211a90297bD90D7f", + "configEncryptionPublicKey": "4d2f75f98b911c20fe7808384312d8b913e6b7a98c34d05c6e461434c92b4502", + "keyBundleID": "e6d6ffec6cff01ac20d57bc42626c8e955293f232d383bf468351d867a7b8213" + } + }, + "payeeAddress": "", + "csaKey": "b473091fe1d4dbbc26ad71c67b4432f8f4280e06bab5e2122a92f4ab8b6ff2f5", + "isConnected": true, + "isEnabled": true + }, + "cl-keystone-one-8": { + "nodeID": "node_7iTc33UzaAj6XmGa5hHC9", + "isBootstrap": false, + "ocrKeys": { + "aptos-testnet": { + "offchainPublicKey": "c791d2b9d3562f991af68ab7164a19734d551a9404d91c9571fdcdc5dcb237ca", + "onchainPublicKey": "bddafb20cc50d89e0ae2f244908c27b1d639615d8186b28c357669de3359f208", + "peerID": "p2p_12D3KooWAUagqMycsro27kFznSQRHbhfCBLx8nKD4ptTiUGDe38c", + "transmitAccount": " ", + "configEncryptionPublicKey": "0874e6cd5c8e651ab0ff564a474832ed9eaf2c5025b553f908d04921d9777d50", + "keyBundleID": "6726df46033038b724a4e6371807b6aa09efc829d0a3f7a5db4fd7df4b69fea7" + }, + "ethereum-testnet-sepolia": { + "offchainPublicKey": "ad08c2a5878cada53521f4e2bb449f191ccca7899246721a0deeea19f7b83f70", + "onchainPublicKey": "8c2aa1e6fad88a6006dfb116eb866cbad2910314", + "peerID": "p2p_12D3KooWAUagqMycsro27kFznSQRHbhfCBLx8nKD4ptTiUGDe38c", + "transmitAccount": "0x31B179dcF8f9036C30f04bE578793e51bF14A39E", + "configEncryptionPublicKey": "e3d4d7a7372a3b1110db0290ab3649eb5fbb0daf6cf3ae02cfe5f367700d9264", + "keyBundleID": "be0d639de3ae3cbeaa31ca369514f748ba1d271145cba6796bcc12aace2f64c3" + } + }, + "payeeAddress": "", + "csaKey": "1141dd1e46797ced9b0fbad49115f18507f6f6e6e3cc86e7e5ba169e58645adc", + "isConnected": true, + "isEnabled": true + }, + "cl-keystone-one-9": { + "nodeID": "node_V3xAXNftjt6sxkfRgmw9J", + "isBootstrap": false, + "ocrKeys": { + "aptos-testnet": { + "offchainPublicKey": "ff1144bbf648e6f76c58d0ce53a9a2cbe9a284d52db8691a714cac8e3a96b8b4", + "onchainPublicKey": "4fa557850e4d5c21b3963c97414c1f37792700c4d3b8abdb904b765fd47e39bf", + "peerID": "p2p_12D3KooWBCMCCZZ8x57AXvJvpCujqhZzTjWXbReaRE8TxNr5dM4U", + "transmitAccount": " ", + "configEncryptionPublicKey": "6a1f37f06833c55ecf46233439ea6179a835bac6f2b2dee725b747c121813149", + "keyBundleID": "d834cf7c830df7510228b33b138c018ff16b4eecf82273ed3bcd862bbbc046d4" + }, + "ethereum-testnet-sepolia": { + "offchainPublicKey": "c805572b813a072067eab2087ddbee8aa719090e12890b15c01094f0d3f74a5f", + "onchainPublicKey": "679296b7c1eb4948efcc87efc550940a182e610c", + "peerID": "p2p_12D3KooWBCMCCZZ8x57AXvJvpCujqhZzTjWXbReaRE8TxNr5dM4U", + "transmitAccount": "0x0b04cE574E80Da73191Ec141c0016a54A6404056", + "configEncryptionPublicKey": "09fced0207611ed618bf0759ab128d9797e15b18e46436be1a56a91e4043ec0e", + "keyBundleID": "1c28e76d180d1ed1524e61845fa58a384415de7e51017edf1f8c553e28357772" + } + }, + "payeeAddress": "", + "csaKey": "412dc6fe48ea4e34baaa77da2e3b032d39b938597b6f3d61fe7ed183a827a431", + "isConnected": true, + "isEnabled": true + } +} \ No newline at end of file diff --git a/deployment/keystone/types.go b/deployment/keystone/types.go index e5657657ed9..b7bf636c3e2 100644 --- a/deployment/keystone/types.go +++ b/deployment/keystone/types.go @@ -1,7 +1,6 @@ package keystone import ( - "encoding/hex" "errors" "fmt" "slices" @@ -15,11 +14,8 @@ import ( "github.com/smartcontractkit/chainlink/deployment" - v1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" ) @@ -55,147 +51,50 @@ type Nop struct { NodeIDs []string // nodes run by this operator } -// ocr2Node is a subset of the node configuration that is needed to register a node -// with the capabilities registry. Signer and P2PKey are chain agnostic. -// TODO: KS-466 when we migrate fully to the JD offchain client, we should be able remove this shim and use environment.Node directly -type ocr2Node struct { - ID string - Signer [32]byte // note that in capabilities registry we need a [32]byte, but in the forwarder we need a common.Address [20]byte - P2PKey p2pkey.PeerID - EncryptionPublicKey [32]byte - IsBoostrap bool - // useful when have to register the ocr3 contract config - p2pKeyBundle *v1.OCR2Config_P2PKeyBundle - ethOcr2KeyBundle *v1.OCR2Config_OCRKeyBundle - aptosOcr2KeyBundle *v1.OCR2Config_OCRKeyBundle - csaKey string // *v1.Node.PublicKey - accountAddress string -} - -func (o *ocr2Node) signerAddress() common.Address { - // eth address is the first 20 bytes of the Signer - return common.BytesToAddress(o.Signer[:20]) -} - -func (o *ocr2Node) toNodeKeys() NodeKeys { +func toNodeKeys(o *deployment.Node, registryChainSel uint64) NodeKeys { var aptosOcr2KeyBundleId string var aptosOnchainPublicKey string - if o.aptosOcr2KeyBundle != nil { - aptosOcr2KeyBundleId = o.aptosOcr2KeyBundle.BundleId - aptosOnchainPublicKey = o.aptosOcr2KeyBundle.OnchainSigningAddress + var aptosCC *deployment.OCRConfig + for details, cfg := range o.SelToOCRConfig { + if family, err := chainsel.GetSelectorFamily(details.ChainSelector); err == nil && family == chainsel.FamilyAptos { + aptosCC = &cfg + break + } + } + if aptosCC != nil { + aptosOcr2KeyBundleId = aptosCC.KeyBundleID + aptosOnchainPublicKey = fmt.Sprintf("%x", aptosCC.OnchainPublicKey[:]) + } + registryChainID, err := chainsel.ChainIdFromSelector(registryChainSel) + if err != nil { + panic(err) } + registryChainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(strconv.Itoa(int(registryChainID)), chainsel.FamilyEVM) + if err != nil { + panic(err) + } + evmCC := o.SelToOCRConfig[registryChainDetails] return NodeKeys{ - EthAddress: o.accountAddress, - P2PPeerID: strings.TrimPrefix(o.p2pKeyBundle.PeerId, "p2p_"), - OCR2BundleID: o.ethOcr2KeyBundle.BundleId, - OCR2OnchainPublicKey: o.ethOcr2KeyBundle.OnchainSigningAddress, - OCR2OffchainPublicKey: o.ethOcr2KeyBundle.OffchainPublicKey, - OCR2ConfigPublicKey: o.ethOcr2KeyBundle.ConfigPublicKey, - CSAPublicKey: o.csaKey, + EthAddress: string(evmCC.TransmitAccount), + P2PPeerID: strings.TrimPrefix(o.PeerID.String(), "p2p_"), + OCR2BundleID: evmCC.KeyBundleID, + OCR2OffchainPublicKey: fmt.Sprintf("%x", evmCC.OffchainPublicKey[:]), + OCR2OnchainPublicKey: fmt.Sprintf("%x", evmCC.OnchainPublicKey[:]), + OCR2ConfigPublicKey: fmt.Sprintf("%x", evmCC.ConfigEncryptionPublicKey[:]), + CSAPublicKey: o.CSAKey, // default value of encryption public key is the CSA public key // TODO: DEVSVCS-760 - EncryptionPublicKey: strings.TrimPrefix(o.csaKey, "csa_"), + EncryptionPublicKey: strings.TrimPrefix(o.CSAKey, "csa_"), // TODO Aptos support. How will that be modeled in clo data? + // TODO: AptosAccount is unset but probably unused AptosBundleID: aptosOcr2KeyBundleId, AptosOnchainPublicKey: aptosOnchainPublicKey, } } -func newOcr2NodeFromJD(n *Node, registryChainSel uint64) (*ocr2Node, error) { - if n.PublicKey == nil { - return nil, errors.New("no public key") - } - // the chain configs are equivalent as far as the ocr2 config is concerned so take the first one - if len(n.ChainConfigs) == 0 { - return nil, errors.New("no chain configs") - } - // all nodes should have an evm chain config, specifically the registry chain - evmCC, err := registryChainConfig(n.ChainConfigs, v1.ChainType_CHAIN_TYPE_EVM, registryChainSel) - if err != nil { - return nil, fmt.Errorf("failed to get registry chain config for sel %d: %w", registryChainSel, err) - } - cfgs := map[chaintype.ChainType]*v1.ChainConfig{ - chaintype.EVM: evmCC, - } - aptosCC, exists := firstChainConfigByType(n.ChainConfigs, v1.ChainType_CHAIN_TYPE_APTOS) - if exists { - cfgs[chaintype.Aptos] = aptosCC - } - return newOcr2Node(n.ID, cfgs, *n.PublicKey) -} - -func ExtractKeys(n *Node, registerChainSel uint64) (p2p p2pkey.PeerID, signer [32]byte, encPubKey [32]byte, err error) { - orc2n, err := newOcr2NodeFromJD(n, registerChainSel) - if err != nil { - return p2p, signer, encPubKey, fmt.Errorf("failed to create ocr2 node for node %s: %w", n.ID, err) - } - return orc2n.P2PKey, orc2n.Signer, orc2n.EncryptionPublicKey, nil -} - -func newOcr2Node(id string, ccfgs map[chaintype.ChainType]*v1.ChainConfig, csaPubKey string) (*ocr2Node, error) { - if ccfgs == nil { - return nil, errors.New("nil ocr2config") - } - evmCC, exists := ccfgs[chaintype.EVM] - if !exists { - return nil, errors.New("no evm chain config for node id " + id) - } - - if csaPubKey == "" { - return nil, errors.New("empty csa public key") - } - // parse csapublic key to - csaKey, err := hex.DecodeString(csaPubKey) - if err != nil { - return nil, fmt.Errorf("failed to decode csa public key %s: %w", csaPubKey, err) - } - if len(csaKey) != 32 { - return nil, fmt.Errorf("invalid csa public key '%s'. expected len 32 got %d", csaPubKey, len(csaKey)) - } - var csaKeyb [32]byte - copy(csaKeyb[:], csaKey) - - ocfg := evmCC.Ocr2Config - p := p2pkey.PeerID{} - if err := p.UnmarshalString(ocfg.P2PKeyBundle.PeerId); err != nil { - return nil, fmt.Errorf("failed to unmarshal peer id %s: %w", ocfg.P2PKeyBundle.PeerId, err) - } - - signer := ocfg.OcrKeyBundle.OnchainSigningAddress - if len(signer) != 40 { - return nil, fmt.Errorf("invalid onchain signing address %s", ocfg.OcrKeyBundle.OnchainSigningAddress) - } - signerB, err := hex.DecodeString(signer) - if err != nil { - return nil, fmt.Errorf("failed to convert signer %s: %w", signer, err) - } - - var sigb [32]byte - copy(sigb[:], signerB) - - n := &ocr2Node{ - ID: id, - Signer: sigb, - P2PKey: p, - EncryptionPublicKey: csaKeyb, - IsBoostrap: ocfg.IsBootstrap, - p2pKeyBundle: ocfg.P2PKeyBundle, - ethOcr2KeyBundle: evmCC.Ocr2Config.OcrKeyBundle, - aptosOcr2KeyBundle: nil, - accountAddress: evmCC.AccountAddress, - csaKey: csaPubKey, - } - // aptos chain config is optional - if aptosCC, exists := ccfgs[chaintype.Aptos]; exists { - n.aptosOcr2KeyBundle = aptosCC.Ocr2Config.OcrKeyBundle - } - - return n, nil -} - -func makeNodeKeysSlice(nodes []*ocr2Node) []NodeKeys { +func makeNodeKeysSlice(nodes []deployment.Node, registryChainSel uint64) []NodeKeys { var out []NodeKeys for _, n := range nodes { - out = append(out, n.toNodeKeys()) + out = append(out, toNodeKeys(&n, registryChainSel)) } return out } @@ -255,21 +154,6 @@ func NodeOperator(name string, adminAddress string) capabilities_registry.Capabi } } -func AdminAddress(n *Node, chainSel uint64) (string, error) { - cid, err := chainsel.ChainIdFromSelector(chainSel) - if err != nil { - return "", fmt.Errorf("failed to get chain id from selector %d: %w", chainSel, err) - } - cidStr := strconv.FormatUint(cid, 10) - for _, chain := range n.ChainConfigs { - //TODO validate chainType field - if chain.Chain.Id == cidStr { - return chain.AdminAddress, nil - } - } - return "", fmt.Errorf("no chain config for chain %d", cid) -} - func nopsToNodes(donInfos []DonInfo, dons []DonCapabilities, chainSelector uint64) (map[capabilities_registry.CapabilitiesRegistryNodeOperator][]string, error) { out := make(map[capabilities_registry.CapabilitiesRegistryNodeOperator][]string) for _, don := range dons { @@ -281,28 +165,23 @@ func nopsToNodes(donInfos []DonInfo, dons []DonCapabilities, chainSelector uint6 return nil, fmt.Errorf("couldn't find donInfo for %v", don.Name) } donInfo := donInfos[idx] - idx = slices.IndexFunc(donInfo.Nodes, func(node Node) bool { - return node.P2PID == nop.Nodes[0] + idx = slices.IndexFunc(donInfo.Nodes, func(node deployment.Node) bool { + return node.PeerID.String() == nop.Nodes[0] }) if idx < 0 { - return nil, fmt.Errorf("couldn't find node with p2p_id %v", nop.Nodes[0]) + return nil, fmt.Errorf("couldn't find node with p2p_id '%v'", nop.Nodes[0]) } node := donInfo.Nodes[idx] - a, err := AdminAddress(&node, chainSelector) - if err != nil { - return nil, fmt.Errorf("failed to get admin address for node %s: %w", node.ID, err) - } + a := node.AdminAddr nodeOperator := NodeOperator(nop.Name, a) for _, node := range nop.Nodes { - - idx = slices.IndexFunc(donInfo.Nodes, func(n Node) bool { - return n.P2PID == node + idx = slices.IndexFunc(donInfo.Nodes, func(n deployment.Node) bool { + return n.PeerID.String() == node }) if idx < 0 { - return nil, fmt.Errorf("couldn't find node with p2p_id %v", node) + return nil, fmt.Errorf("couldn't find node with p2p_id '%v'", node) } - out[nodeOperator] = append(out[nodeOperator], donInfo.Nodes[idx].ID) - + out[nodeOperator] = append(out[nodeOperator], donInfo.Nodes[idx].NodeID) } } } @@ -321,70 +200,62 @@ func mapDonsToCaps(dons []DonInfo) map[string][]kcr.CapabilitiesRegistryCapabili // mapDonsToNodes returns a map of don name to simplified representation of their nodes // all nodes must have evm config and ocr3 capability nodes are must also have an aptos chain config -func mapDonsToNodes(dons []DonInfo, excludeBootstraps bool, registryChainSel uint64) (map[string][]*ocr2Node, error) { - donToOcr2Nodes := make(map[string][]*ocr2Node) +func mapDonsToNodes(dons []DonInfo, excludeBootstraps bool, registryChainSel uint64) (map[string][]deployment.Node, error) { + donToNodes := make(map[string][]deployment.Node) // get the nodes for each don from the offchain client, get ocr2 config from one of the chain configs for the node b/c - // they are equivalent, and transform to ocr2node representation + // they are equivalent for _, don := range dons { for _, node := range don.Nodes { - ocr2n, err := newOcr2NodeFromJD(&node, registryChainSel) - if err != nil { - return nil, fmt.Errorf("failed to create ocr2 node for node %s: %w", node.ID, err) - } - if excludeBootstraps && ocr2n.IsBoostrap { + if excludeBootstraps && node.IsBootstrap { continue } - if _, ok := donToOcr2Nodes[don.Name]; !ok { - donToOcr2Nodes[don.Name] = make([]*ocr2Node, 0) + if _, ok := donToNodes[don.Name]; !ok { + donToNodes[don.Name] = make([]deployment.Node, 0) } - donToOcr2Nodes[don.Name] = append(donToOcr2Nodes[don.Name], ocr2n) - } - } - - return donToOcr2Nodes, nil -} - -func firstChainConfigByType(ccfgs []*v1.ChainConfig, t v1.ChainType) (*v1.ChainConfig, bool) { - for _, c := range ccfgs { - if c.Chain.Type == t { - return c, true + donToNodes[don.Name] = append(donToNodes[don.Name], node) } } - return nil, false -} -func registryChainConfig(ccfgs []*v1.ChainConfig, t v1.ChainType, sel uint64) (*v1.ChainConfig, error) { - chainId, err := chainsel.ChainIdFromSelector(sel) - if err != nil { - return nil, fmt.Errorf("failed to get chain id from selector %d: %w", sel, err) - } - chainIdStr := strconv.FormatUint(chainId, 10) - for _, c := range ccfgs { - if c.Chain.Type == t && c.Chain.Id == chainIdStr { - return c, nil - } - } - return nil, fmt.Errorf("no chain config for chain %d", chainId) + return donToNodes, nil } // RegisteredDon is a representation of a don that exists in the in the capabilities registry all with the enriched node data type RegisteredDon struct { Name string Info capabilities_registry.CapabilitiesRegistryDONInfo - Nodes []*ocr2Node + Nodes []deployment.Node } -func (d RegisteredDon) signers() []common.Address { +func (d RegisteredDon) signers(chainFamily string) []common.Address { sort.Slice(d.Nodes, func(i, j int) bool { - return d.Nodes[i].P2PKey.String() < d.Nodes[j].P2PKey.String() + return d.Nodes[i].PeerID.String() < d.Nodes[j].PeerID.String() }) var out []common.Address for _, n := range d.Nodes { - if n.IsBoostrap { + if n.IsBootstrap { continue } - out = append(out, n.signerAddress()) + var found bool + var registryChainDetails chainsel.ChainDetails + for details, _ := range n.SelToOCRConfig { + if family, err := chainsel.GetSelectorFamily(details.ChainSelector); err == nil && family == chainFamily { + found = true + registryChainDetails = details + + } + } + if !found { + panic(fmt.Sprintf("chainType not found: %v", chainFamily)) + } + // eth address is the first 20 bytes of the Signer + config, exists := n.SelToOCRConfig[registryChainDetails] + if !exists { + panic(fmt.Sprintf("chainID not found: %v", registryChainDetails)) + } + signer := config.OnchainPublicKey + signerAddress := common.BytesToAddress(signer) + out = append(out, signerAddress) } return out } diff --git a/deployment/keystone/types_test.go b/deployment/keystone/types_test.go index 925649bba0d..ea122837aa6 100644 --- a/deployment/keystone/types_test.go +++ b/deployment/keystone/types_test.go @@ -1,402 +1,78 @@ package keystone import ( + "encoding/hex" + "fmt" + "math/big" + "strconv" + "strings" "testing" - "github.com/stretchr/testify/assert" - - v1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/ethereum/go-ethereum/common" + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/require" ) -func Test_newOcr2Node(t *testing.T) { - type args struct { - id string - ccfgs map[chaintype.ChainType]*v1.ChainConfig - csaPubKey string +func Test_toNodeKeys(t *testing.T) { + registryChainSel := chainsel.TEST_90000001 + registryChainID, err := chainsel.ChainIdFromSelector(registryChainSel.Selector) + if err != nil { + panic(err) + } + registryChainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(strconv.Itoa(int(registryChainID)), chainsel.FamilyEVM) + if err != nil { + panic(err) + } + aptosChainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(strconv.Itoa(int(1)), chainsel.FamilyAptos) + if err != nil { + panic(err) } - tests := []struct { - name string - args args - wantAptos bool - wantErr bool - }{ - { - name: "no aptos", - args: args{ - id: "1", - ccfgs: map[chaintype.ChainType]*v1.ChainConfig{ - chaintype.EVM: { - Ocr2Config: &v1.OCR2Config{ - P2PKeyBundle: &v1.OCR2Config_P2PKeyBundle{ - PeerId: "p2p_12D3KooWMWUKdoAc2ruZf9f55p7NVFj7AFiPm67xjQ8BZBwkqyYv", - PublicKey: "pubKey", - }, - OcrKeyBundle: &v1.OCR2Config_OCRKeyBundle{ - BundleId: "bundleId", - ConfigPublicKey: "03dacd15fc96c965c648e3623180de002b71a97cf6eeca9affb91f461dcd6ce1", - OffchainPublicKey: "03dacd15fc96c965c648e3623180de002b71a97cf6eeca9affb91f461dcd6ce1", - OnchainSigningAddress: "b35409a8d4f9a18da55c5b2bb08a3f5f68d44442", - }, - }, - }, - }, - csaPubKey: "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", + p2pID := p2pkey.MustNewV2XXXTestingOnly(big.NewInt(100)) + pubKey_1 := "11114981a6119ca3f932cdb8c402d71a72d672adae7849f581ecff8b8e1098e7" // valid csa key + signing_1 := common.Hex2Bytes("11117293a4Cc2621b61193135a95928735e4795f") // valid eth address + admin_1 := common.HexToAddress("0x1111567890123456789012345678901234567890") // valid eth address + signing_2 := common.Hex2Bytes("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") // valid key + var encryptionpubkey [32]byte + if _, err := hex.Decode(encryptionpubkey[:], []byte(pubKey_1)); err != nil { + panic(fmt.Sprintf("failed to decode pubkey %s: %v", encryptionpubkey, err)) + } + keys := toNodeKeys(&deployment.Node{ + NodeID: "p2p_123", + Name: "node 1", + PeerID: p2pID.PeerID(), + CSAKey: pubKey_1, + AdminAddr: admin_1.String(), + SelToOCRConfig: map[chainsel.ChainDetails]deployment.OCRConfig{ + registryChainDetails: { + OffchainPublicKey: types.OffchainPublicKey(common.FromHex("1111111111111111111111111111111111111111111111111111111111111111")), + OnchainPublicKey: signing_1[:], + PeerID: p2pID.PeerID(), + TransmitAccount: types.Account(admin_1.String()), + ConfigEncryptionPublicKey: encryptionpubkey, + KeyBundleID: "abcd", }, - }, - { - name: "with aptos", - args: args{ - id: "1", - ccfgs: map[chaintype.ChainType]*v1.ChainConfig{ - chaintype.EVM: { - - Ocr2Config: &v1.OCR2Config{ - P2PKeyBundle: &v1.OCR2Config_P2PKeyBundle{ - PeerId: "p2p_12D3KooWMWUKdoAc2ruZf9f55p7NVFj7AFiPm67xjQ8BZBwkqyYv", - PublicKey: "pubKey", - }, - OcrKeyBundle: &v1.OCR2Config_OCRKeyBundle{ - BundleId: "bundleId", - ConfigPublicKey: "03dacd15fc96c965c648e3623180de002b71a97cf6eeca9affb91f461dcd6ce1", - OffchainPublicKey: "03dacd15fc96c965c648e3623180de002b71a97cf6eeca9affb91f461dcd6ce1", - OnchainSigningAddress: "b35409a8d4f9a18da55c5b2bb08a3f5f68d44442", - }, - }, - }, - chaintype.Aptos: { - - Ocr2Config: &v1.OCR2Config{ - P2PKeyBundle: &v1.OCR2Config_P2PKeyBundle{ - PeerId: "p2p_12D3KooWMWUKdoAc2ruZf9f55p7NVFj7AFiPm67xjQ8BZB11111", - PublicKey: "pubKey", - }, - OcrKeyBundle: &v1.OCR2Config_OCRKeyBundle{ - BundleId: "bundleId2", - ConfigPublicKey: "0000015fc96c965c648e3623180de002b71a97cf6eeca9affb91f461dcd6ce1", - OffchainPublicKey: "03dacd15fc96c965c648e3623180de002b71a97cf6eeca9affb91f461dcd6ce1", - OnchainSigningAddress: "111409a8d4f9a18da55c5b2bb08a3f5f68d44777", - }, - }, - }, - }, - csaPubKey: "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", + aptosChainDetails: { + TransmitAccount: "ff", + OnchainPublicKey: signing_2, + KeyBundleID: "aptos", }, - wantAptos: true, }, - { - name: "bad csa key", - args: args{ - id: "1", - ccfgs: map[chaintype.ChainType]*v1.ChainConfig{ - chaintype.EVM: { + }, registryChainSel.Selector) - Ocr2Config: &v1.OCR2Config{ - P2PKeyBundle: &v1.OCR2Config_P2PKeyBundle{ - PeerId: "p2p_12D3KooWMWUKdoAc2ruZf9f55p7NVFj7AFiPm67xjQ8BZBwkqyYv", - PublicKey: "pubKey", - }, - OcrKeyBundle: &v1.OCR2Config_OCRKeyBundle{ - BundleId: "bundleId", - ConfigPublicKey: "03dacd15fc96c965c648e3623180de002b71a97cf6eeca9affb91f461dcd6ce1", - OffchainPublicKey: "03dacd15fc96c965c648e3623180de002b71a97cf6eeca9affb91f461dcd6ce1", - OnchainSigningAddress: "b35409a8d4f9a18da55c5b2bb08a3f5f68d44442", - }, - }, - }, - }, - csaPubKey: "not hex", - }, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := newOcr2Node(tt.args.id, tt.args.ccfgs, tt.args.csaPubKey) - if (err != nil) != tt.wantErr { - t.Errorf("newOcr2Node() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.wantErr { - return - } - assert.NotNil(t, got.ethOcr2KeyBundle) - assert.NotNil(t, got.p2pKeyBundle) - assert.NotNil(t, got.Signer) - assert.NotNil(t, got.EncryptionPublicKey) - assert.NotEmpty(t, got.csaKey) - assert.NotEmpty(t, got.P2PKey) - assert.Equal(t, tt.wantAptos, got.aptosOcr2KeyBundle != nil) - }) - } + require.Equal(t, NodeKeys{ + EthAddress: admin_1.String(), + AptosBundleID: "aptos", + AptosOnchainPublicKey: hex.EncodeToString(signing_2), + P2PPeerID: strings.TrimPrefix(p2pID.PeerID().String(), "p2p_"), + OCR2BundleID: "abcd", + OCR2OnchainPublicKey: hex.EncodeToString(signing_1), + OCR2OffchainPublicKey: "1111111111111111111111111111111111111111111111111111111111111111", + OCR2ConfigPublicKey: pubKey_1, + CSAPublicKey: pubKey_1, + EncryptionPublicKey: pubKey_1, + }, keys) } - -// func Test_mapDonsToNodes(t *testing.T) { -// var ( -// pubKey = "03dacd15fc96c965c648e3623180de002b71a97cf6eeca9affb91f461dcd6ce1" -// evmSig = "b35409a8d4f9a18da55c5b2bb08a3f5f68d44442" -// aptosSig = "b35409a8d4f9a18da55c5b2bb08a3f5f68d44442b35409a8d4f9a18da55c5b2bb08a3f5f68d44442" -// peerID = "p2p_12D3KooWMWUKdoAc2ruZf9f55p7NVFj7AFiPm67xjQ8BZBwkqyYv" -// // todo: these should be defined in common -// writerCap = 3 -// ocr3Cap = 2 -// registryChainSel = chainsel.ETHEREUM_TESTNET_SEPOLIA.Selector -// registryChainID = strconv.FormatUint(chainsel.ETHEREUM_TESTNET_SEPOLIA.EvmChainID, 10) -// ) -// type args struct { -// dons []DonCapabilities -// excludeBootstraps bool -// } -// tests := []struct { -// name string -// args args -// wantErr bool -// }{ -// { -// name: "writer evm only", -// args: args{ -// dons: []DonCapabilities{ -// { -// Name: "ok writer", -// Nops: []*models.NodeOperator{ -// { -// Nodes: []*models.Node{ -// { -// PublicKey: &pubKey, -// ChainConfigs: []*models.NodeChainConfig{ -// { -// ID: "1", -// Network: &models.Network{ -// ChainType: models.ChainTypeEvm, -// ChainID: registryChainID, -// }, -// Ocr2Config: &models.NodeOCR2Config{ -// P2pKeyBundle: &models.NodeOCR2ConfigP2PKeyBundle{ -// PeerID: peerID, -// }, -// OcrKeyBundle: &models.NodeOCR2ConfigOCRKeyBundle{ -// ConfigPublicKey: pubKey, -// OffchainPublicKey: pubKey, -// OnchainSigningAddress: evmSig, -// }, -// }, -// }, -// }, -// }, -// }, -// }, -// }, -// Capabilities: []kcr.CapabilitiesRegistryCapability{ -// { -// LabelledName: "writer", -// Version: "1", -// CapabilityType: uint8(writerCap), -// }, -// }, -// }, -// }, -// }, -// wantErr: false, -// }, -// { -// name: "err if no evm chain", -// args: args{ -// dons: []DonCapabilities{ -// { -// Name: "bad chain", -// Nops: []*models.NodeOperator{ -// { -// Nodes: []*models.Node{ -// { -// PublicKey: &pubKey, -// ChainConfigs: []*models.NodeChainConfig{ -// { -// ID: "1", -// Network: &models.Network{ -// ChainType: models.ChainTypeSolana, -// }, -// Ocr2Config: &models.NodeOCR2Config{ -// P2pKeyBundle: &models.NodeOCR2ConfigP2PKeyBundle{ -// PeerID: peerID, -// }, -// OcrKeyBundle: &models.NodeOCR2ConfigOCRKeyBundle{ -// ConfigPublicKey: pubKey, -// OffchainPublicKey: pubKey, -// OnchainSigningAddress: evmSig, -// }, -// }, -// }, -// }, -// }, -// }, -// }, -// }, -// Capabilities: []kcr.CapabilitiesRegistryCapability{ -// { -// LabelledName: "writer", -// Version: "1", -// CapabilityType: uint8(writerCap), -// }, -// }, -// }, -// }, -// }, -// wantErr: true, -// }, -// { -// name: "ocr3 cap evm only", -// args: args{ -// dons: []DonCapabilities{ -// { -// Name: "bad chain", -// Nops: []*models.NodeOperator{ -// { -// Nodes: []*models.Node{ -// { -// PublicKey: &pubKey, -// ChainConfigs: []*models.NodeChainConfig{ -// { -// ID: "1", -// Network: &models.Network{ -// ChainType: models.ChainTypeEvm, -// ChainID: registryChainID, -// }, -// Ocr2Config: &models.NodeOCR2Config{ -// P2pKeyBundle: &models.NodeOCR2ConfigP2PKeyBundle{ -// PeerID: peerID, -// }, -// OcrKeyBundle: &models.NodeOCR2ConfigOCRKeyBundle{ -// ConfigPublicKey: pubKey, -// OffchainPublicKey: pubKey, -// OnchainSigningAddress: evmSig, -// }, -// }, -// }, -// }, -// }, -// }, -// }, -// }, -// Capabilities: []kcr.CapabilitiesRegistryCapability{ -// { -// LabelledName: "ocr3", -// Version: "1", -// CapabilityType: uint8(ocr3Cap), -// }, -// }, -// }, -// }, -// }, -// wantErr: false, -// }, -// { -// name: "ocr3 cap evm & aptos", -// args: args{ -// dons: []DonCapabilities{ -// { -// Name: "ok chain", -// Nops: []*models.NodeOperator{ -// { -// Nodes: []*models.Node{ -// { -// PublicKey: &pubKey, -// ChainConfigs: []*models.NodeChainConfig{ -// { -// ID: "1", -// Network: &models.Network{ -// ChainType: models.ChainTypeEvm, -// ChainID: registryChainID, -// }, -// Ocr2Config: &models.NodeOCR2Config{ -// P2pKeyBundle: &models.NodeOCR2ConfigP2PKeyBundle{ -// PeerID: peerID, -// }, -// OcrKeyBundle: &models.NodeOCR2ConfigOCRKeyBundle{ -// ConfigPublicKey: pubKey, -// OffchainPublicKey: pubKey, -// OnchainSigningAddress: evmSig, -// }, -// }, -// }, -// { -// ID: "2", -// Network: &models.Network{ -// ChainType: models.ChainTypeAptos, -// }, -// Ocr2Config: &models.NodeOCR2Config{ -// P2pKeyBundle: &models.NodeOCR2ConfigP2PKeyBundle{ -// PeerID: peerID, -// }, -// OcrKeyBundle: &models.NodeOCR2ConfigOCRKeyBundle{ -// ConfigPublicKey: pubKey, -// OffchainPublicKey: pubKey, -// OnchainSigningAddress: aptosSig, -// }, -// }, -// }, -// }, -// }, -// }, -// }, -// }, -// Capabilities: []kcr.CapabilitiesRegistryCapability{ -// { -// LabelledName: "ocr3", -// Version: "1", -// CapabilityType: uint8(ocr3Cap), -// }, -// }, -// }, -// }, -// }, -// wantErr: false, -// }, -// } -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// _, err := mapDonsToNodes(tt.args.dons, tt.args.excludeBootstraps, registryChainSel) -// if (err != nil) != tt.wantErr { -// t.Errorf("mapDonsToNodes() error = %v, wantErr %v", err, tt.wantErr) -// return -// } -// }) -// } -// // make sure the clo test data is correct -// wfNops := loadTestNops(t, "testdata/workflow_nodes.json") -// cwNops := loadTestNops(t, "testdata/chain_writer_nodes.json") -// assetNops := loadTestNops(t, "testdata/asset_nodes.json") -// require.Len(t, wfNops, 10) -// require.Len(t, cwNops, 10) -// require.Len(t, assetNops, 16) - -// wfDon := DonCapabilities{ -// Name: WFDonName, -// Nops: wfNops, -// Capabilities: []kcr.CapabilitiesRegistryCapability{OCR3Cap}, -// } -// cwDon := DonCapabilities{ -// Name: TargetDonName, -// Nops: cwNops, -// Capabilities: []kcr.CapabilitiesRegistryCapability{WriteChainCap}, -// } -// assetDon := DonCapabilities{ -// Name: StreamDonName, -// Nops: assetNops, -// Capabilities: []kcr.CapabilitiesRegistryCapability{StreamTriggerCap}, -// } -// _, err := mapDonsToNodes([]DonCapabilities{wfDon}, false, registryChainSel) -// require.NoError(t, err, "failed to map wf don") -// _, err = mapDonsToNodes([]DonCapabilities{cwDon}, false, registryChainSel) -// require.NoError(t, err, "failed to map cw don") -// _, err = mapDonsToNodes([]DonCapabilities{assetDon}, false, registryChainSel) -// require.NoError(t, err, "failed to map asset don") -// } - -// func loadTestNops(t *testing.T, pth string) []*models.NodeOperator { -// f, err := os.ReadFile(pth) -// require.NoError(t, err) -// var nops []*models.NodeOperator -// require.NoError(t, json.Unmarshal(f, &nops)) -// return nops -// } diff --git a/go.mod b/go.mod index 6c39f32a8c1..fc5a63c446f 100644 --- a/go.mod +++ b/go.mod @@ -74,10 +74,10 @@ require ( github.com/scylladb/go-reflectx v1.0.1 github.com/shirou/gopsutil/v3 v3.24.3 github.com/shopspring/decimal v1.4.0 - github.com/smartcontractkit/chain-selectors v1.0.30 + github.com/smartcontractkit/chain-selectors v1.0.31 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241114154055-8d29ea018b57 github.com/smartcontractkit/chainlink-feeds v0.1.1 diff --git a/go.sum b/go.sum index 7a003d0b83e..9565c08cf26 100644 --- a/go.sum +++ b/go.sum @@ -1072,14 +1072,14 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartcontractkit/chain-selectors v1.0.30 h1:jk+xVRocgQ/uvKLSd1JzeHJ/v+EKu1BjrreaSGqKzjo= -github.com/smartcontractkit/chain-selectors v1.0.30/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= +github.com/smartcontractkit/chain-selectors v1.0.31 h1:oRHyK88KnsCh4OdU2hr0u70pm3KUgyMDyK0v0aOtUk4= +github.com/smartcontractkit/chain-selectors v1.0.31/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec h1:5vS1k8Qn09p8SQ3JzvS8iy4Pve7s3aVq+UPIdl74smY= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec/go.mod h1:4adKaHNaxFsRvV/lYfqtbsWyyvIPUMLR0FdOJN/ljis= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b h1:mm46AlaafEhvGjJvuAb0VoLLM3NKAVnwKZ+iUCNL/sg= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b/go.mod h1:ny87uTW6hLjCTLiBqBRNFEhETSXhHWevYlPclT5lSco= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d h1:0tnjo1gpG16PHAouXamgDAAu6e7PWaM0Ppq6dMWnjx0= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d/go.mod h1:ny87uTW6hLjCTLiBqBRNFEhETSXhHWevYlPclT5lSco= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f h1:BwrIaQIx5Iy6eT+DfLhFfK2XqjxRm74mVdlX8gbu4dw= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f/go.mod h1:wHtwSR3F1CQSJJZDQKuqaqFYnvkT+kMyget7dl8Clvo= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241114154055-8d29ea018b57 h1:1BMTG66HnCIz+KMBWGvyzELNM6VHGwv2WKFhN7H49Sg= diff --git a/integration-tests/ccip-tests/contracts/contract_deployer.go b/integration-tests/ccip-tests/contracts/contract_deployer.go index 07ed6e5dd8e..c97e7bbc0aa 100644 --- a/integration-tests/ccip-tests/contracts/contract_deployer.go +++ b/integration-tests/ccip-tests/contracts/contract_deployer.go @@ -21,9 +21,10 @@ import ( ocrconfighelper2 "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2/types" - "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" + "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/deployment/environment/nodeclient" "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/wrappers" @@ -505,6 +506,7 @@ func (e *CCIPContractsDeployer) DeployLockReleaseTokenPoolContract(tokenAddr str auth, wrappers.MustNewWrappedContractBackend(e.evmClient, nil), token, + 18, []common.Address{}, rmnProxy, true, diff --git a/integration-tests/ccip-tests/contracts/contract_models.go b/integration-tests/ccip-tests/contracts/contract_models.go index 15b5ed8cd0d..376f70192d2 100644 --- a/integration-tests/ccip-tests/contracts/contract_models.go +++ b/integration-tests/ccip-tests/contracts/contract_models.go @@ -478,14 +478,13 @@ func (w TokenPoolWrapper) IsSupportedChain(opts *bind.CallOpts, remoteChainSelec func (w TokenPoolWrapper) ApplyChainUpdates(opts *bind.TransactOpts, update []token_pool.TokenPoolChainUpdate) (*types.Transaction, error) { if w.Latest != nil && w.Latest.PoolInterface != nil { - return w.Latest.PoolInterface.ApplyChainUpdates(opts, update) + return w.Latest.PoolInterface.ApplyChainUpdates(opts, []uint64{}, update) } if w.V1_4_0 != nil && w.V1_4_0.PoolInterface != nil { V1_4_0Updates := make([]token_pool_1_4_0.TokenPoolChainUpdate, len(update)) for i, u := range update { V1_4_0Updates[i] = token_pool_1_4_0.TokenPoolChainUpdate{ RemoteChainSelector: u.RemoteChainSelector, - Allowed: u.Allowed, InboundRateLimiterConfig: token_pool_1_4_0.RateLimiterConfig{ IsEnabled: u.InboundRateLimiterConfig.IsEnabled, Capacity: u.InboundRateLimiterConfig.Capacity, @@ -828,9 +827,8 @@ func (pool *TokenPool) SetRemoteChainOnPool(remoteChainSelector uint64, remotePo selectorsToUpdate = append(selectorsToUpdate, token_pool.TokenPoolChainUpdate{ RemoteChainSelector: remoteChainSelector, - RemotePoolAddress: encodedPoolAddress, + RemotePoolAddresses: [][]byte{encodedPoolAddress}, RemoteTokenAddress: encodedTokenAddress, - Allowed: true, InboundRateLimiterConfig: token_pool.RateLimiterConfig{ IsEnabled: true, Capacity: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e9)), diff --git a/integration-tests/ccip-tests/testconfig/tomls/contract-version1.4.toml b/integration-tests/ccip-tests/testconfig/tomls/contract-version1.4.toml deleted file mode 100644 index 392b058e5c8..00000000000 --- a/integration-tests/ccip-tests/testconfig/tomls/contract-version1.4.toml +++ /dev/null @@ -1,13 +0,0 @@ -[CCIP] -[CCIP.ContractVersions] -PriceRegistry = '1.2.0' -OffRamp = '1.2.0' -OnRamp = '1.2.0' -TokenPool = '1.4.0' -CommitStore = '1.2.0' - -[CCIP.Groups.smoke.TokenConfig] -CCIPOwnerTokens = true - -[CCIP.Groups.load.TokenConfig] -CCIPOwnerTokens = true \ No newline at end of file diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 2446eb69ecf..ee2aca39965 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -35,10 +35,10 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/slack-go/slack v0.15.0 github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 - github.com/smartcontractkit/chain-selectors v1.0.30 + github.com/smartcontractkit/chain-selectors v1.0.31 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.16 github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 6762ce52dfd..eab9d9f18b0 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1399,14 +1399,14 @@ github.com/slack-go/slack v0.15.0 h1:LE2lj2y9vqqiOf+qIIy0GvEoxgF1N5yLGZffmEZykt0 github.com/slack-go/slack v0.15.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 h1:qQH6fZZe31nBAG6INHph3z5ysDTPptyu0TR9uoJ1+ok= github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86/go.mod h1:WtWOoVQQEHxRHL2hNmuRrvDfYfQG/CioFNoa9Rr2mBE= -github.com/smartcontractkit/chain-selectors v1.0.30 h1:jk+xVRocgQ/uvKLSd1JzeHJ/v+EKu1BjrreaSGqKzjo= -github.com/smartcontractkit/chain-selectors v1.0.30/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= +github.com/smartcontractkit/chain-selectors v1.0.31 h1:oRHyK88KnsCh4OdU2hr0u70pm3KUgyMDyK0v0aOtUk4= +github.com/smartcontractkit/chain-selectors v1.0.31/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec h1:5vS1k8Qn09p8SQ3JzvS8iy4Pve7s3aVq+UPIdl74smY= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec/go.mod h1:4adKaHNaxFsRvV/lYfqtbsWyyvIPUMLR0FdOJN/ljis= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b h1:mm46AlaafEhvGjJvuAb0VoLLM3NKAVnwKZ+iUCNL/sg= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b/go.mod h1:ny87uTW6hLjCTLiBqBRNFEhETSXhHWevYlPclT5lSco= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d h1:0tnjo1gpG16PHAouXamgDAAu6e7PWaM0Ppq6dMWnjx0= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d/go.mod h1:ny87uTW6hLjCTLiBqBRNFEhETSXhHWevYlPclT5lSco= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f h1:BwrIaQIx5Iy6eT+DfLhFfK2XqjxRm74mVdlX8gbu4dw= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f/go.mod h1:wHtwSR3F1CQSJJZDQKuqaqFYnvkT+kMyget7dl8Clvo= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241114154055-8d29ea018b57 h1:1BMTG66HnCIz+KMBWGvyzELNM6VHGwv2WKFhN7H49Sg= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 422aeef8c62..2a20af58814 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,7 +17,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.15.0 - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.16 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.9 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.2 @@ -397,7 +397,7 @@ require ( github.com/shoenig/test v0.6.6 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/chain-selectors v1.0.30 // indirect + github.com/smartcontractkit/chain-selectors v1.0.31 // indirect github.com/smartcontractkit/chainlink-automation v0.8.1 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 0b03ccf5293..c4ffe9e0841 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1388,14 +1388,14 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.15.0 h1:LE2lj2y9vqqiOf+qIIy0GvEoxgF1N5yLGZffmEZykt0= github.com/slack-go/slack v0.15.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/smartcontractkit/chain-selectors v1.0.30 h1:jk+xVRocgQ/uvKLSd1JzeHJ/v+EKu1BjrreaSGqKzjo= -github.com/smartcontractkit/chain-selectors v1.0.30/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= +github.com/smartcontractkit/chain-selectors v1.0.31 h1:oRHyK88KnsCh4OdU2hr0u70pm3KUgyMDyK0v0aOtUk4= +github.com/smartcontractkit/chain-selectors v1.0.31/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec h1:5vS1k8Qn09p8SQ3JzvS8iy4Pve7s3aVq+UPIdl74smY= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241118091009-43c2b4804cec/go.mod h1:4adKaHNaxFsRvV/lYfqtbsWyyvIPUMLR0FdOJN/ljis= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b h1:mm46AlaafEhvGjJvuAb0VoLLM3NKAVnwKZ+iUCNL/sg= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241120111740-a6a70ec7692b/go.mod h1:ny87uTW6hLjCTLiBqBRNFEhETSXhHWevYlPclT5lSco= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d h1:0tnjo1gpG16PHAouXamgDAAu6e7PWaM0Ppq6dMWnjx0= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241125150608-97ceadb2072d/go.mod h1:ny87uTW6hLjCTLiBqBRNFEhETSXhHWevYlPclT5lSco= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f h1:BwrIaQIx5Iy6eT+DfLhFfK2XqjxRm74mVdlX8gbu4dw= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241017133723-5277829bd53f/go.mod h1:wHtwSR3F1CQSJJZDQKuqaqFYnvkT+kMyget7dl8Clvo= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241114154055-8d29ea018b57 h1:1BMTG66HnCIz+KMBWGvyzELNM6VHGwv2WKFhN7H49Sg= diff --git a/integration-tests/smoke/ccip/ccip_batching_test.go b/integration-tests/smoke/ccip/ccip_batching_test.go index d85924c1739..0667d1367cc 100644 --- a/integration-tests/smoke/ccip/ccip_batching_test.go +++ b/integration-tests/smoke/ccip/ccip_batching_test.go @@ -13,6 +13,7 @@ import ( "golang.org/x/exp/maps" "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/integration-tests/testsetups" @@ -51,8 +52,8 @@ func Test_CCIPBatching(t *testing.T) { ) // connect sourceChain1 and sourceChain2 to destChain - require.NoError(t, changeset.AddLaneWithDefaultPrices(e.Env, state, sourceChain1, destChain)) - require.NoError(t, changeset.AddLaneWithDefaultPrices(e.Env, state, sourceChain2, destChain)) + require.NoError(t, changeset.AddLaneWithDefaultPricesAndFeeQuoterConfig(e.Env, state, sourceChain1, destChain, false)) + require.NoError(t, changeset.AddLaneWithDefaultPricesAndFeeQuoterConfig(e.Env, state, sourceChain2, destChain, false)) const ( numMessages = 5 diff --git a/integration-tests/smoke/ccip/ccip_messaging_test.go b/integration-tests/smoke/ccip/ccip_messaging_test.go index a8aa4bea916..446f21898a0 100644 --- a/integration-tests/smoke/ccip/ccip_messaging_test.go +++ b/integration-tests/smoke/ccip/ccip_messaging_test.go @@ -62,7 +62,7 @@ func Test_CCIPMessaging(t *testing.T) { ", dest chain selector:", destChain, ) // connect a single lane, source to dest - require.NoError(t, changeset.AddLaneWithDefaultPrices(e.Env, state, sourceChain, destChain)) + require.NoError(t, changeset.AddLaneWithDefaultPricesAndFeeQuoterConfig(e.Env, state, sourceChain, destChain, false)) var ( replayed bool diff --git a/integration-tests/smoke/ccip/fee_boosting_test.go b/integration-tests/smoke/ccip/fee_boosting_test.go index 1f9b1f9083a..4d331c20b7d 100644 --- a/integration-tests/smoke/ccip/fee_boosting_test.go +++ b/integration-tests/smoke/ccip/fee_boosting_test.go @@ -88,7 +88,7 @@ func Test_CCIPFeeBoosting(t *testing.T) { } func runFeeboostTestCase(tc feeboostTestCase) { - require.NoError(tc.t, changeset.AddLane(tc.deployedEnv.Env, tc.onchainState, tc.sourceChain, tc.destChain, tc.initialPrices)) + require.NoError(tc.t, changeset.AddLaneWithDefaultPricesAndFeeQuoterConfig(tc.deployedEnv.Env, tc.onchainState, tc.sourceChain, tc.destChain, false)) startBlocks := make(map[uint64]*uint64) expectedSeqNum := make(map[changeset.SourceDestPair]uint64) diff --git a/integration-tests/testsetups/test_helpers.go b/integration-tests/testsetups/test_helpers.go index f11b343f155..57c25e58a46 100644 --- a/integration-tests/testsetups/test_helpers.go +++ b/integration-tests/testsetups/test_helpers.go @@ -195,6 +195,7 @@ func NewLocalDevEnvironment( tokenConfig := changeset.NewTestTokenConfig(state.Chains[feedSel].USDFeeds) usdcCCTPConfig := make(map[cciptypes.ChainSelector]pluginconfig.USDCCCTPTokenConfig) timelocksPerChain := make(map[uint64]*gethwrappers.RBACTimelock) + ocrParams := make(map[uint64]changeset.CCIPOCRParams) for _, chain := range usdcChains { require.NotNil(t, state.Chains[chain].MockUSDCTokenMessenger) require.NotNil(t, state.Chains[chain].MockUSDCTransmitter) @@ -203,7 +204,6 @@ func NewLocalDevEnvironment( SourcePoolAddress: state.Chains[chain].USDCTokenPool.Address().String(), SourceMessageTransmitterAddr: state.Chains[chain].MockUSDCTransmitter.Address().String(), } - timelocksPerChain[chain] = state.Chains[chain].Timelock } var usdcAttestationCfg changeset.USDCAttestationConfig if len(usdcChains) > 0 { @@ -217,7 +217,10 @@ func NewLocalDevEnvironment( APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond), } } - + for _, chain := range allChains { + timelocksPerChain[chain] = state.Chains[chain].Timelock + ocrParams[chain] = changeset.DefaultOCRParams(feedSel, nil, nil) + } // Deploy second set of changesets to deploy and configure the CCIP contracts. env, err = commonchangeset.ApplyChangesets(t, env, timelocksPerChain, []commonchangeset.ChangesetApplication{ { @@ -228,6 +231,7 @@ func NewLocalDevEnvironment( ChainsToDeploy: allChains, TokenConfig: tokenConfig, OCRSecrets: deployment.XXXGenerateTestOCRSecrets(), + OCRParams: ocrParams, USDCConfig: changeset.USDCConfig{ EnabledChains: usdcChains, USDCAttestationConfig: usdcAttestationCfg, @@ -347,7 +351,7 @@ func GenerateTestRMNConfig(t *testing.T, nRMNNodes int, tenv changeset.DeployedE HomeChain: devenv.HomeChain{ Name: MustCCIPNameToRMNName(hc.Name), CapabilitiesRegistry: state.Chains[tenv.HomeChainSel].CapabilityRegistry.Address().String(), - CCIPConfig: state.Chains[tenv.HomeChainSel].CCIPHome.Address().String(), + CCIPHome: state.Chains[tenv.HomeChainSel].CCIPHome.Address().String(), RMNHome: state.Chains[tenv.HomeChainSel].RMNHome.Address().String(), }, RemoteChains: remoteChains, diff --git a/tools/bin/go_core_ccip_deployment_tests b/tools/bin/go_core_ccip_deployment_tests index 5249496cc0a..de976741398 100755 --- a/tools/bin/go_core_ccip_deployment_tests +++ b/tools/bin/go_core_ccip_deployment_tests @@ -3,26 +3,18 @@ set -o pipefail set +e SCRIPT_PATH=`dirname "$0"`; SCRIPT_PATH=`eval "cd \"$SCRIPT_PATH\" && pwd"` -OUTPUT_FILE="../output.txt" -USE_TEE="${USE_TEE:-true}" +OUTPUT_FILE=${OUTPUT_FILE:-"../output.txt"} +EXTRA_FLAGS="" cd ./deployment || exit go mod download -echo "Failed tests and panics: ---------------------" +echo "Test execution results: ---------------------" echo "" + if [[ $GITHUB_EVENT_NAME == "schedule" ]]; then - if [[ $DEBUG == "true" ]]; then - go test -json -vet=off ./... -covermode=atomic -coverpkg=./... -coverprofile=coverage.txt | tee $OUTPUT_FILE - else - go test -json -vet=off ./... -covermode=atomic -coverpkg=./... -coverprofile=coverage.txt | cat > $OUTPUT_FILE - fi -else - if [[ $DEBUG == "true" ]]; then - go test -vet=off ./... | tee $OUTPUT_FILE - else - go test -vet=off ./... | cat > $OUTPUT_FILE - fi + EXTRA_FLAGS="-covermode=atomic -coverpkg=./... -coverprofile=coverage.txt" fi +go test ./... "$EXTRA_FLAGS" | tee $OUTPUT_FILE | grep -Ev '\[no test files\]|\[no tests to run\]' EXITCODE=${PIPESTATUS[0]} # Assert no known sensitive strings present in test logger output diff --git a/tools/bin/go_core_fuzz b/tools/bin/go_core_fuzz index 49aaf33b65e..65c9273a418 100755 --- a/tools/bin/go_core_fuzz +++ b/tools/bin/go_core_fuzz @@ -19,7 +19,7 @@ echo "timeout minutes: $FUZZ_TIMEOUT_MINUTES" echo "fuzz seconds: $FUZZ_SECONDS" echo "Failed fuzz tests and panics: ---------------------" echo "" -timeout "${FUZZ_TIMEOUT_MINUTES}"m ./fuzz/fuzz_all_native.py --ci --seconds "$FUZZ_SECONDS" --go_module_root ./ | tee $OUTPUT_FILE +timeout "${FUZZ_TIMEOUT_MINUTES}"m ./fuzz/fuzz_all_native.py --ci --seconds "$FUZZ_SECONDS" --go_module_root ./ | tee $OUTPUT_FILE | grep -Ev '\[no test files\]|\[no tests to run\]' EXITCODE=${PIPESTATUS[0]} # Assert no known sensitive strings present in test logger output diff --git a/tools/bin/go_core_race_tests b/tools/bin/go_core_race_tests index 2c4071bc20f..467dda4e92f 100755 --- a/tools/bin/go_core_race_tests +++ b/tools/bin/go_core_race_tests @@ -4,21 +4,9 @@ OUTPUT_FILE=${OUTPUT_FILE:-"./output.txt"} TIMEOUT="${TIMEOUT:-10s}" COUNT="${COUNT:-5}" -echo "Failed tests and panics: ---------------------" +echo "Test execution results: ---------------------" echo "" -if [[ $GITHUB_EVENT_NAME == "schedule" ]]; then - if [[ $DEBUG == "true" ]]; then - GORACE="log_path=$PWD/race" go test -json -vet=off -race -shuffle on -timeout "$TIMEOUT" -count "$COUNT" $1 | tee $OUTPUT_FILE - else - GORACE="log_path=$PWD/race" go test -vet=off -race -shuffle on -timeout "$TIMEOUT" -count "$COUNT" $1 | cat > $OUTPUT_FILE - fi -else - if [[ $DEBUG == "true" ]]; then - GORACE="log_path=$PWD/race" go test -json -vet=off -race -shuffle on -timeout "$TIMEOUT" -count "$COUNT" $1 | tee $OUTPUT_FILE - else - GORACE="log_path=$PWD/race" go test -vet=off -race -shuffle on -timeout "$TIMEOUT" -count "$COUNT" $1 | cat > $OUTPUT_FILE - fi -fi +GORACE="log_path=$PWD/race" go test -race -shuffle on -timeout "$TIMEOUT" -count "$COUNT" $1 | cat > $OUTPUT_FILE EXITCODE=${PIPESTATUS[0]} diff --git a/tools/bin/go_core_tests b/tools/bin/go_core_tests index 90713e15563..0fffcb72a39 100755 --- a/tools/bin/go_core_tests +++ b/tools/bin/go_core_tests @@ -4,22 +4,14 @@ set +e SCRIPT_PATH=`dirname "$0"`; SCRIPT_PATH=`eval "cd \"$SCRIPT_PATH\" && pwd"` OUTPUT_FILE=${OUTPUT_FILE:-"./output.txt"} +EXTRA_FLAGS="" -echo "Failed tests and panics: ---------------------" +echo "Test execution results: ---------------------" echo "" if [[ $GITHUB_EVENT_NAME == "schedule" ]]; then - if [[ $DEBUG == "true" ]]; then - go test -json -vet=off -covermode=atomic -coverpkg=./... -coverprofile=coverage.txt $1 | tee $OUTPUT_FILE - else - go test -json -vet=off -covermode=atomic -coverpkg=./... -coverprofile=coverage.txt $1 | cat > $OUTPUT_FILE - fi -else - if [[ $DEBUG == "true" ]]; then - go test -vet=off $1 | tee $OUTPUT_FILE - else - go test -vet=off $1 | cat > $OUTPUT_FILE - fi + EXTRA_FLAGS="-covermode=atomic -coverpkg=./... -coverprofile=coverage.txt" fi +go test "$EXTRA_FLAGS" $1 | tee $OUTPUT_FILE | grep -Ev '\[no test files\]|\[no tests to run\]' EXITCODE=${PIPESTATUS[0]} # Assert no known sensitive strings present in test logger output diff --git a/tools/bin/go_core_tests_integration b/tools/bin/go_core_tests_integration index 6dfe22583cd..323e9d526ac 100755 --- a/tools/bin/go_core_tests_integration +++ b/tools/bin/go_core_tests_integration @@ -4,6 +4,7 @@ set +e SCRIPT_PATH=$(dirname "$0"); SCRIPT_PATH=$(eval "cd \"$SCRIPT_PATH\" && pwd") OUTPUT_FILE=${OUTPUT_FILE:-"./output.txt"} +EXTRA_FLAGS="" echo "Finding and running integration-tagged tests" INTEGRATION_TAGGED_TEST_FILES=$(find . -name '*_test.go' -exec grep -l '//go:build integration' {} +) @@ -14,24 +15,15 @@ fi INTEGRATION_TEST_DIRS=$(echo "$INTEGRATION_TAGGED_TEST_FILES" | xargs -n1 dirname | sort -u) INTEGRATION_TEST_DIRS_SPACE_DELIMITED=$(echo "$INTEGRATION_TEST_DIRS" | tr '\n' ' ') -echo "Failed tests and panics: ---------------------" +echo "Test execution results: ---------------------" echo "" if [[ $GITHUB_EVENT_NAME == "schedule" ]]; then # Experimental code to minimize size of this coverage report # ALL_IMPORTS=$(go list -f '{{ join .Imports "\n" }}' $INTEGRATION_TEST_DIRS | sort -u) # COVERPKG_DIRS=$(echo "$INTEGRATION_TEST_DIRS $ALL_IMPORTS" | grep "smartcontractkit/chainlink" | tr '\n' ',') - if [[ $DEBUG == "true" ]]; then - go test -json -tags integration -vet=off -covermode=atomic -coverpkg=./... -coverprofile=coverage.txt $INTEGRATION_TEST_DIRS_SPACE_DELIMITED | tee $OUTPUT_FILE - else - go test -json -tags integration -vet=off -covermode=atomic -coverpkg=./... -coverprofile=coverage.txt $INTEGRATION_TEST_DIRS_SPACE_DELIMITED | cat > $OUTPUT_FILE - fi -else - if [[ $DEBUG == "true" ]]; then - go test -vet=off -tags integration $INTEGRATION_TEST_DIRS_SPACE_DELIMITED | tee $OUTPUT_FILE - else - go test -vet=off -tags integration $INTEGRATION_TEST_DIRS_SPACE_DELIMITED | cat > $OUTPUT_FILE - fi + EXTRA_FLAGS="-covermode=atomic -coverpkg=./... -coverprofile=coverage.txt" fi +go test -tags integration "$EXTRA_FLAGS" $INTEGRATION_TEST_DIRS_SPACE_DELIMITED | tee $OUTPUT_FILE | grep -Ev '\[no test files\]|\[no tests to run\]' EXITCODE=${PIPESTATUS[0]} # Assert no known sensitive strings present in test logger output